{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:22.531537Z",
     "start_time": "2024-08-05T08:06:12.808806Z"
    },
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "JHSdxPJuN4x7",
    "outputId": "a74dc274-dd24-4415-a3e4-1fcff4e437a2"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sys.version_info(major=3, minor=12, micro=3, releaselevel='final', serial=0)\n",
      "matplotlib 3.9.0\n",
      "numpy 1.26.4\n",
      "pandas 2.2.2\n",
      "sklearn 1.5.0\n",
      "torch 2.3.1+cpu\n",
      "cpu\n"
     ]
    }
   ],
   "source": [
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import sklearn\n",
    "import pandas as pd\n",
    "import os\n",
    "import sys\n",
    "import time\n",
    "from tqdm.auto import tqdm\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "print(sys.version_info)\n",
    "for module in mpl, np, pd, sklearn, torch:\n",
    "    print(module.__name__, module.__version__)\n",
    "\n",
    "device = torch.device(\"cuda:0\") if torch.cuda.is_available() else torch.device(\"cpu\")\n",
    "print(device)\n",
    "\n",
    "seed = 42\n",
    "torch.manual_seed(seed)\n",
    "torch.cuda.manual_seed_all(seed)\n",
    "np.random.seed(seed)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:22.541540Z",
     "start_time": "2024-08-05T08:06:22.530536400Z"
    },
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "yQQEArYqWylq",
    "outputId": "bc80eeee-442a-4ff2-f69e-348314f84bce"
   },
   "outputs": [],
   "source": [
    "#挂载谷歌云盘\n",
    "\n",
    "# from google.colab import drive\n",
    "# drive.mount('/content/drive')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:22.552601Z",
     "start_time": "2024-08-05T08:06:22.536531800Z"
    },
    "id": "wzS4AimwWz7f"
   },
   "outputs": [],
   "source": [
    "# !cp /content/drive/MyDrive/transformer-de-en/* . -r"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "May I borrow this book?\n",
      "¿Puedo tomar prestado este libro?\n"
     ]
    }
   ],
   "source": [
    "import unicodedata\n",
    "import re\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "#因为西班牙语有一些是特殊字符，所以我们需要unicode转ascii，\n",
    "# 这样值变小了，因为unicode太大\n",
    "def unicode_to_ascii(s):\n",
    "    #NFD是转换方法，把每一个字节拆开，Mn是重音，所以去除\n",
    "    return ''.join(c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn')\n",
    "\n",
    "#下面我们找个样本测试一下\n",
    "# 加u代表对字符串进行unicode编码\n",
    "en_sentence = u\"May I borrow this book?\"\n",
    "sp_sentence = u\"¿Puedo tomar prestado este libro?\"\n",
    "\n",
    "print(unicode_to_ascii(en_sentence))\n",
    "print(unicode_to_ascii(sp_sentence))\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "may i borrow this book ?\n",
      "¿ puedo tomar prestado este libro ?\n",
      "b'\\xc2\\xbf puedo tomar prestado este libro ?'\n"
     ]
    }
   ],
   "source": [
    "def preprocess_sentence(w):\n",
    "    #变为小写，去掉多余的空格，变成小写，id少一些\n",
    "    w = unicode_to_ascii(w.lower().strip())\n",
    "\n",
    "    # 在单词与跟在其后的标点符号之间插入一个空格\n",
    "    # eg: \"he is a boy.\" => \"he is a boy . \"\n",
    "    # Reference:- https://stackoverflow.com/questions/3645931/python-padding-punctuation-with-white-spaces-keeping-punctuation\n",
    "    w = re.sub(r\"([?.!,¿])\", r\" \\1 \", w)\n",
    "    #因为可能有多余空格，替换为一个空格，所以处理一下\n",
    "    w = re.sub(r'[\" \"]+', \" \", w)\n",
    "\n",
    "    # 除了 (a-z, A-Z, \".\", \"?\", \"!\", \",\")，将所有字符替换为空格\n",
    "    w = re.sub(r\"[^a-zA-Z?.!,¿]+\", \" \", w)\n",
    "\n",
    "    w = w.rstrip().strip()\n",
    "\n",
    "    return w\n",
    "\n",
    "print(preprocess_sentence(en_sentence))\n",
    "print(preprocess_sentence(sp_sentence))\n",
    "print(preprocess_sentence(sp_sentence).encode('utf-8'))  #¿是占用两个字节的"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(1, 4, 7), (2, 5, 8)]\n"
     ]
    }
   ],
   "source": [
    "#zip例子\n",
    "a = [[1,2],[4,5],[7,8]]\n",
    "zipped = list(zip(*a))\n",
    "print(zipped)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array(['train', 'test', 'train', 'train', 'train', 'train', 'train',\n",
       "       'train', 'train', 'train', 'train', 'test', 'train', 'train',\n",
       "       'train', 'train', 'train', 'train', 'train', 'train', 'train',\n",
       "       'train', 'train', 'train', 'train', 'train', 'train', 'train',\n",
       "       'train', 'train', 'train', 'train', 'train', 'test', 'test',\n",
       "       'train', 'train', 'train', 'train', 'train', 'train', 'train',\n",
       "       'train', 'test', 'train', 'train', 'train', 'train', 'train',\n",
       "       'train', 'test', 'train', 'test', 'train', 'train', 'test',\n",
       "       'train', 'train', 'train', 'train', 'train', 'train', 'train',\n",
       "       'train', 'train', 'train', 'train', 'train', 'train', 'test',\n",
       "       'train', 'train', 'train', 'train', 'train', 'train', 'train',\n",
       "       'train', 'train', 'train', 'train', 'train', 'train', 'train',\n",
       "       'train', 'train', 'train', 'train', 'train', 'train', 'train',\n",
       "       'train', 'train', 'train', 'train', 'train', 'train', 'train',\n",
       "       'train', 'train'], dtype='<U5')"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "split_index1 = np.random.choice(a=[\"train\", \"test\"], replace=True, p=[0.9, 0.1], size=100)\n",
    "split_index1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pathlib import Path\n",
    "from torch.utils.data import Dataset, DataLoader\n",
    "\n",
    "class LangPairDataset(Dataset):\n",
    "    fpath = Path(r\"./data_spa_en/spa.txt\") #数据文件路径\n",
    "    cache_path = Path(r\"./.cache/lang_pair.npy\") #缓存文件路径\n",
    "    split_index = np.random.choice(a=[\"train\", \"test\"], replace=True, p=[0.9, 0.1], size=118964) #按照9:1划分训练集和测试集\n",
    "    def __init__(self, mode=\"train\", cache=False):\n",
    "        if cache or not self.cache_path.exists():#如果没有缓存，或者缓存不存在，就处理一下数据\n",
    "            self.cache_path.parent.mkdir(parents=True, exist_ok=True) #创建缓存文件夹，如果存在就忽略\n",
    "            with open(self.fpath, \"r\", encoding=\"utf8\") as file:\n",
    "                lines = file.readlines()\n",
    "                lang_pair = [[preprocess_sentence(w) for w in l.split('\\t')]  for l in lines] #处理数据，变成list((src, trg))的形式\n",
    "                trg, src = zip(*lang_pair) #分离出目标语言和源语言\n",
    "                trg=np.array(trg) #转换为numpy数组\n",
    "                src=np.array(src) #转换为numpy数组\n",
    "                np.save(self.cache_path, {\"trg\": trg, \"src\": src})  #保存为npy文件,方便下次直接读取,不用再处理\n",
    "        else:\n",
    "            lang_pair = np.load(self.cache_path, allow_pickle=True).item() #读取npy文件，allow_pickle=True允许读取字典\n",
    "            trg = lang_pair[\"trg\"]\n",
    "            src = lang_pair[\"src\"]\n",
    "\n",
    "        self.trg = trg[self.split_index == mode] #按照index拿到训练集的 标签语言 --英语\n",
    "        self.src = src[self.split_index == mode] #按照index拿到训练集的源语言 --西班牙\n",
    "\n",
    "    def __getitem__(self, index):\n",
    "        return self.src[index], self.trg[index]\n",
    "\n",
    "    def __len__(self):\n",
    "        return len(self.src)\n",
    "\n",
    "\n",
    "train_ds = LangPairDataset(\"train\")\n",
    "test_ds = LangPairDataset(\"test\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "source: si quieres sonar como un hablante nativo , debes estar dispuesto a practicar diciendo la misma frase una y otra vez de la misma manera en que un musico de banjo practica el mismo fraseo una y otra vez hasta que lo puedan tocar correctamente y en el tiempo esperado .\n",
      "target: if you want to sound like a native speaker , you must be willing to practice saying the same sentence over and over in the same way that banjo players practice the same phrase over and over until they can play it correctly and at the desired tempo .\n"
     ]
    }
   ],
   "source": [
    "print(\"source: {}\\ntarget: {}\".format(*train_ds[-1]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Tokenizer\n",
    "\n",
    "这里有两种处理方式，分别对应着 encoder 和 decoder 的 word embedding 是否共享，这里实现不共享的方案。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "word count: 23715\n",
      "word count: 12500\n"
     ]
    }
   ],
   "source": [
    "from collections import Counter\n",
    "\n",
    "def get_word_idx(ds, mode=\"src\", threshold=2):\n",
    "    #载入词表，看下词表长度，词表就像英语字典\n",
    "    word2idx = {\n",
    "        \"[PAD]\": 0,     # 填充 token\n",
    "        \"[BOS]\": 1,     # begin of sentence\n",
    "        \"[UNK]\": 2,     # 未知 token\n",
    "        \"[EOS]\": 3,     # end of sentence\n",
    "    }\n",
    "    idx2word = {value: key for key, value in word2idx.items()}\n",
    "    index = len(idx2word)\n",
    "    threshold = 1  # 出现次数低于此的token舍弃\n",
    "    #如果数据集有很多个G，那是用for循环的，不能' '.join\n",
    "    word_list = \" \".join([pair[0 if mode==\"src\" else 1] for pair in ds]).split()\n",
    "    counter = Counter(word_list) #统计词频,counter类似字典，key是单词，value是出现次数\n",
    "    print(\"word count:\", len(counter))\n",
    "\n",
    "    for token, count in counter.items():\n",
    "        if count >= threshold:#出现次数大于阈值的token加入词表\n",
    "            word2idx[token] = index #加入词表\n",
    "            idx2word[index] = token #加入反向词表\n",
    "            index += 1\n",
    "\n",
    "    return word2idx, idx2word\n",
    "\n",
    "src_word2idx, src_idx2word = get_word_idx(train_ds, \"src\") #源语言词表\n",
    "trg_word2idx, trg_idx2word = get_word_idx(train_ds, \"trg\") #目标语言词表"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "raw text----------\n",
      "['hello', 'world']\n",
      "['tokenize', 'text', 'datas', 'with', 'batch']\n",
      "['this', 'is', 'a', 'test']\n",
      "mask----------\n",
      "tensor([0, 0, 0, 0, 1, 1, 1])\n",
      "tensor([0, 0, 0, 0, 0, 0, 0])\n",
      "tensor([0, 0, 0, 0, 0, 0, 1])\n",
      "indices----------\n",
      "tensor([   1,   16, 3218,    3,    0,    0,    0])\n",
      "tensor([   1,    2, 3878,    2,  552,    2,    3])\n",
      "tensor([   1,  117,  235,  103, 2896,    3,    0])\n",
      "decode text----------\n",
      "[BOS] hello world [EOS] [PAD] [PAD] [PAD]\n",
      "[BOS] [UNK] text [UNK] with [UNK] [EOS]\n",
      "[BOS] this is a test [EOS] [PAD]\n"
     ]
    }
   ],
   "source": [
    "class Tokenizer:\n",
    "    def __init__(self, word2idx, idx2word, max_length=500, pad_idx=0, bos_idx=1, eos_idx=3, unk_idx=2):\n",
    "        self.word2idx = word2idx\n",
    "        self.idx2word = idx2word\n",
    "        self.max_length = max_length\n",
    "        self.pad_idx = pad_idx\n",
    "        self.bos_idx = bos_idx\n",
    "        self.eos_idx = eos_idx\n",
    "        self.unk_idx = unk_idx\n",
    "\n",
    "    def encode(self, text_list, padding_first=False, add_bos=True, add_eos=True, return_mask=False):\n",
    "        \"\"\"如果padding_first == True，则padding加载前面，否则加载后面\n",
    "        return_mask: 是否返回mask(掩码），mask用于指示哪些是padding的，哪些是真实的token\n",
    "        \"\"\"\n",
    "        max_length = min(self.max_length, add_eos + add_bos + max([len(text) for text in text_list]))\n",
    "        indices_list = []\n",
    "        for text in text_list:\n",
    "            indices = [self.word2idx.get(word, self.unk_idx) for word in text[:max_length - add_bos - add_eos]] #如果词表中没有这个词，就用unk_idx代替，indices是一个list,里面是每个词的index,也就是一个样本的index\n",
    "            if add_bos:\n",
    "                indices = [self.bos_idx] + indices\n",
    "            if add_eos:\n",
    "                indices = indices + [self.eos_idx]\n",
    "            if padding_first:#padding加载前面，超参可以调\n",
    "                indices = [self.pad_idx] * (max_length - len(indices)) + indices\n",
    "            else:#padding加载后面\n",
    "                indices = indices + [self.pad_idx] * (max_length - len(indices))\n",
    "            indices_list.append(indices)\n",
    "        input_ids = torch.tensor(indices_list) #转换为tensor\n",
    "        masks = (input_ids == self.pad_idx).to(dtype=torch.int64) #mask是一个和input_ids一样大小的tensor，0代表token，1代表padding，mask用于去除padding的影响\n",
    "        return input_ids if not return_mask else (input_ids, masks)\n",
    "\n",
    "\n",
    "    def decode(self, indices_list, remove_bos=True, remove_eos=True, remove_pad=True, split=False):\n",
    "        text_list = []\n",
    "        for indices in indices_list:\n",
    "            text = []\n",
    "            for index in indices:\n",
    "                word = self.idx2word.get(index, \"[UNK]\") #如果词表中没有这个词，就用unk_idx代替\n",
    "                if remove_bos and word == \"[BOS]\":\n",
    "                    continue\n",
    "                if remove_eos and word == \"[EOS]\":#如果到达eos，就结束\n",
    "                    break\n",
    "                if remove_pad and word == \"[PAD]\":#如果到达pad，就结束\n",
    "                    break\n",
    "                text.append(word) #单词添加到列表中\n",
    "            text_list.append(\" \".join(text) if not split else text) #把列表中的单词拼接，变为一个句子\n",
    "        return text_list\n",
    "\n",
    "#两个相对于1个toknizer的好处是embedding的参数量减少\n",
    "src_tokenizer = Tokenizer(word2idx=src_word2idx, idx2word=src_idx2word) #源语言tokenizer\n",
    "trg_tokenizer = Tokenizer(word2idx=trg_word2idx, idx2word=trg_idx2word) #目标语言tokenizer\n",
    "\n",
    "# trg_tokenizer.encode([[\"hello\"], [\"hello\", \"world\"]], add_bos=True, add_eos=False,return_mask=True)\n",
    "raw_text = [\"hello world\".split(), \"tokenize text datas with batch\".split(), \"this is a test\".split()]\n",
    "indices,mask = trg_tokenizer.encode(raw_text, padding_first=False, add_bos=True, add_eos=True,return_mask=True)\n",
    "decode_text = trg_tokenizer.decode(indices.tolist(), remove_bos=False, remove_eos=False, remove_pad=False)\n",
    "print(\"raw text\"+'-'*10)\n",
    "for raw in raw_text:\n",
    "    print(raw)\n",
    "print(\"mask\"+'-'*10)\n",
    "for m in mask:\n",
    "    print(m)\n",
    "print(\"indices\"+'-'*10)\n",
    "for index in indices:\n",
    "    print(index)\n",
    "print(\"decode text\"+'-'*10)\n",
    "for decode in decode_text:\n",
    "    print(decode)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### DataLoader"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "def collate_fct(batch):\n",
    "    src_words = [pair[0].split() for pair in batch]\n",
    "    trg_words = [pair[1].split() for pair in batch]\n",
    "\n",
    "    # [PAD] [BOS] src [EOS]\n",
    "    encoder_inputs, encoder_inputs_mask = src_tokenizer.encode(\n",
    "        src_words, padding_first=True, add_bos=True, add_eos=True, return_mask=True\n",
    "        )\n",
    "\n",
    "    # [BOS] trg [PAD]\n",
    "    decoder_inputs = trg_tokenizer.encode(\n",
    "        trg_words, padding_first=False, add_bos=True, add_eos=False, return_mask=False,\n",
    "        )\n",
    "\n",
    "    # trg [EOS] [PAD]\n",
    "    decoder_labels, decoder_labels_mask = trg_tokenizer.encode(\n",
    "        trg_words, padding_first=False, add_bos=False, add_eos=True, return_mask=True\n",
    "        )\n",
    "\n",
    "    return {\n",
    "        \"encoder_inputs\": encoder_inputs.to(device=device),\n",
    "        \"encoder_inputs_mask\": encoder_inputs_mask.to(device=device),\n",
    "        \"decoder_inputs\": decoder_inputs.to(device=device),\n",
    "        \"decoder_labels\": decoder_labels.to(device=device),\n",
    "        \"decoder_labels_mask\": decoder_labels_mask.to(device=device),\n",
    "    } #当返回的数据较多时，用dict返回比较合理\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "encoder_inputs\n",
      "tensor([[   0,    1,   55,   67, 1056,  306,   50,    5,    3],\n",
      "        [   1,   92, 5604,   50, 2622,  489, 3758,    5,    3]])\n",
      "encoder_inputs_mask\n",
      "tensor([[1, 0, 0, 0, 0, 0, 0, 0, 0],\n",
      "        [0, 0, 0, 0, 0, 0, 0, 0, 0]])\n",
      "decoder_inputs\n",
      "tensor([[   1,   17,   32,  516,   30, 1088, 1577,    5,    0],\n",
      "        [   1,   47, 2976,  689, 5400, 2238,  634,   29,    5]])\n",
      "decoder_labels\n",
      "tensor([[  17,   32,  516,   30, 1088, 1577,    5,    3,    0],\n",
      "        [  47, 2976,  689, 5400, 2238,  634,   29,    5,    3]])\n",
      "decoder_labels_mask\n",
      "tensor([[0, 0, 0, 0, 0, 0, 0, 0, 1],\n",
      "        [0, 0, 0, 0, 0, 0, 0, 0, 0]])\n"
     ]
    }
   ],
   "source": [
    "sample_dl = DataLoader(train_ds, batch_size=2, shuffle=True, collate_fn=collate_fct)\n",
    "\n",
    "for batch in sample_dl:\n",
    "    for key, value in batch.items():\n",
    "        print(key)\n",
    "        print(value)\n",
    "    break"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "55aNBForN4x9"
   },
   "source": [
    "## 数据加载\n",
    "\n",
    "- 采用WMT16的德语和英语平行语料库，数据集主页：[WMT16](https://www.statmt.org/wmt16/multimodal-task.html#task1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "0AadtoM3N4yC"
   },
   "source": [
    "## 定义模型\n",
    "\n",
    "- Transformer模型由Embedding、Transformer-Block组成\n",
    "- Embedding包括：\n",
    "    - WordEmbedding\n",
    "    - PositionEmbedding\n",
    "- Transformer-Block包括：\n",
    "    - Self-Attention\n",
    "    - Cross-Attention\n",
    "    - MLP"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "VTl-sSJmN4yD"
   },
   "source": [
    "### Embedding"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:24.109021500Z",
     "start_time": "2024-08-05T08:06:24.106022800Z"
    },
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 455
    },
    "id": "y66CxrsBN4yD",
    "outputId": "c703025c-afc5-4012-d8e3-0e9d4ad253ec"
   },
   "outputs": [
    {
     "data": {
      "image/png": "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UhK/hnjdpHY02snLG2+8gaysLEybNg3r1q1Djx49MHjw4JN292vIrFq1ChMmTMDq1auxbNkyVFRU4KKLLkJxcbGqM3nyZLz//vt48803sWrVKuzZswdXXXVVEEddt3zzzTd44YUX0L17d1N5Y7zuw4cP49xzz4XD4cDHH3+Mn3/+Gf/85z8RFxen6lQnJX1D49FHH8Xzzz+PZ599Fhs3bsSjjz6Kxx57DM8884yq0xiuu7i4GD169MDcuXN9Hq/ONY4cORIbNmzAsmXL8MEHH+CLL77A+PHjz9QlBERV111SUoJ169bhgQcewLp16/D2229j06ZNuPzyy031GuJ1k1pSo0xIDYh+/foZEyZMUD97PB4jNTXVmDVrVhBHdXrZt2+fAcBYtWqVYRiGkZ+fbzgcDuPNN99UdTZu3GgAMLKzs4M1zDrjyJEjRvv27Y1ly5YZf/zjH4077rjDMIzGe9333nuvMWDAAL/HvV6vkZycbDz++OOqLD8/33C5XMa///3vMzHE08LQoUONv/zlL6ayq666yhg5cqRhGI3zugEY77zzjvq5Otf4888/GwCMb775RtX5+OOPDYvFYuzevfuMjb02nHjdvli7dq0BwNixY4dhGI3juknNaZQrL+Xl5cjJyTGl5rZarcjMzER2dnYQR3Z6Ob5ZUHx8PAAgJycHFRUVpvvQqVMntGzZslHchwkTJmDo0KGm6wMa73W/99576Nu3L66++mo0bdoUvXr1wksvvaSOnyolfUOlf//+WL58OX799VcAwPfff48vv/wSF198MYDGe9061bnG7OxsxMbGom/fvqpOZmYmrFYr1qxZc8bHfLooKCiAxWJBbGwsgNC5bmKm3u+wGwgHDhyAx+M5aRfepKQk/PLLL0Ea1enF6/Vi0qRJOPfcc9G1a1cAQG5uLpxOp/olP05SUhJyc3ODMMq6Y/HixVi3bh2++eabk4411uv+7bff8PzzzyMrKwt/+9vf8M033+D222+H0+nE6NGj1bX5+tw35Ou+7777UFhYiE6dOsFms8Hj8eChhx7CyJEjAaDRXrdOda4xNzcXTZs2NR232+2Ij49vNPehtLQU9957L6677jqVmDEUrpucTKOcvIQiEyZMwE8//YQvv/wy2EM57ezatQt33HEHli1bdsazsgYTr9eLvn374uGHHwZwbLvun376CfPmzcPo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",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\n",
    "class TransformerEmbedding(nn.Module):\n",
    "    def __init__(self, config):\n",
    "        super().__init__()\n",
    "        # hyper params\n",
    "        self.vocab_size = config[\"vocab_size\"]\n",
    "        self.hidden_size = config[\"d_model\"] # 词向量维度\n",
    "        self.pad_idx = config[\"pad_idx\"]\n",
    "        dropout_rate = config[\"dropout\"]\n",
    "        self.max_length = config[\"max_length\"]\n",
    "\n",
    "        # layers,设置padding_idx可以让pad的词向量全为0\n",
    "        self.word_embedding = nn.Embedding(\n",
    "            self.vocab_size, self.hidden_size, padding_idx=self.pad_idx\n",
    "        )\n",
    "        self.pos_embedding = nn.Embedding(\n",
    "            self.max_length,\n",
    "            self.hidden_size,\n",
    "            _weight=self.get_positional_encoding(\n",
    "                self.max_length, self.hidden_size\n",
    "            ),# 位置编码，权重通过get_positional_encoding函数计算得到\n",
    "        )\n",
    "        self.pos_embedding.weight.requires_grad_(False) # 不更新位置编码的权重\n",
    "        self.dropout = nn.Dropout(dropout_rate) # 随机失活层\n",
    "\n",
    "    def get_word_embedding_weights(self):\n",
    "        return self.word_embedding.weight\n",
    "\n",
    "    # 计算位置信息\n",
    "    @classmethod\n",
    "    def get_positional_encoding(self, max_length, hidden_size):#max_length是最大长度，hidden_size是embedding维度相等\n",
    "        # Compute the positional encodings once in log space.\n",
    "        pe = torch.zeros(max_length, hidden_size) # 初始化位置编码\n",
    "        # .unsqueeze(1) 是将这个一维张量转换为二维张量，即将其形状从 (max_length,) 变为 (max_length, 1)。这个操作在张量的维度上增加了一个维度，使其从一维变为二维，第二维的大小为 1。\n",
    "        position = torch.arange(0, max_length).unsqueeze(1) # 位置信息,从0到max_length-1\n",
    "        div_term = torch.exp(\n",
    "            torch.arange(0, hidden_size, 2)\n",
    "            * -(torch.log(torch.Tensor([10000.0])) / hidden_size)\n",
    "        )# 计算位置编码的权重,为了性能考量（是数学上的对数函数分解）\n",
    "        pe[:, 0::2] = torch.sin(position * div_term)\n",
    "        pe[:, 1::2] = torch.cos(position * div_term)\n",
    "        return pe\n",
    "\n",
    "    def forward(self, input_ids):\n",
    "        # input_ids: [batch_size, seq_len]\n",
    "        seq_len = input_ids.shape[1]\n",
    "        assert (\n",
    "            seq_len <= self.max_length\n",
    "        ), f\"input sequence length should no more than {self.max_length} but got {seq_len}\"\n",
    "\n",
    "        position_ids = torch.arange(seq_len, dtype=torch.long, device=input_ids.device)\n",
    "        position_ids = position_ids.unsqueeze(0).expand_as(input_ids)\n",
    "        print(position_ids)\n",
    "        # embedding\n",
    "        word_embeds = self.word_embedding(input_ids) # 词嵌入\n",
    "        pos_embeds = self.pos_embedding(position_ids) # 位置编码\n",
    "        embeds = word_embeds + pos_embeds\n",
    "        embeds = self.dropout(embeds)\n",
    "\n",
    "        return embeds\n",
    "\n",
    "\n",
    "def plot_position_embedding(position_embedding):# 绘制位置编码\n",
    "    plt.pcolormesh(position_embedding) # 绘制位置编码矩阵\n",
    "    plt.xlabel('Depth')\n",
    "    plt.ylabel('Position')\n",
    "    plt.colorbar() # 颜色条，-1到1的颜色范围\n",
    "    plt.show()\n",
    "\n",
    "position_embedding = TransformerEmbedding.get_positional_encoding(64, 128)\n",
    "plot_position_embedding(position_embedding)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:24.109021500Z",
     "start_time": "2024-08-05T08:06:24.107023100Z"
    },
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,\n",
      "         18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,\n",
      "         36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49],\n",
      "        [ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,\n",
      "         18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,\n",
      "         36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]])\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "torch.Size([2, 50, 128])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#随机input，调用TransformerEmbedding\n",
    "config={\n",
    "    \"vocab_size\": 100,\n",
    "    \"d_model\": 128,\n",
    "    \"pad_idx\": 0,\n",
    "    \"max_length\": 64,\n",
    "    \"dropout\": 0.1,\n",
    "}\n",
    "input_ids = torch.randint(0, 100, (2, 50))\n",
    "embeds = TransformerEmbedding(config)(input_ids)\n",
    "embeds.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "wXavO0SNN4yD"
   },
   "source": [
    "### Transformer Block"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "HZL4mu3pN4yD"
   },
   "source": [
    "#### scaled-dot-product-attention"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:24.109021500Z",
     "start_time": "2024-08-05T08:06:24.108022500Z"
    },
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 970
    },
    "id": "U9QwdVQYN4yD",
    "outputId": "b6ae9ac8-c71c-4a7b-fd4b-9c15e92dba2c"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "key_value.shape torch.Size([2, 4, 2])\n",
      "torch.Size([2, 3, 2])\n",
      "torch.Size([2, 2, 3, 4])\n"
     ]
    }
   ],
   "source": [
    "from dataclasses import dataclass\n",
    "from typing import Optional, Tuple\n",
    "\n",
    "Tensor = torch.Tensor\n",
    "\n",
    "@dataclass\n",
    "class AttentionOutput:\n",
    "    hidden_states: Tensor\n",
    "    attn_scores: Tensor\n",
    "\n",
    "class MultiHeadAttention(nn.Module):\n",
    "    def __init__(self, config):\n",
    "        super().__init__()\n",
    "        # hyper params\n",
    "        self.hidden_size = config[\"d_model\"] # 隐藏层大小\n",
    "        self.num_heads = config[\"num_heads\"] # 多头注意力的头数\n",
    "        assert (\n",
    "            self.hidden_size % self.num_heads == 0\n",
    "        ), \"Hidden size must be divisible by num_heads but got {} and {}\".format(\n",
    "            self.hidden_size, self.num_heads\n",
    "        )\n",
    "        self.head_dim = self.hidden_size // self.num_heads # 每个头的维度\n",
    "\n",
    "        # layers\n",
    "        self.Wq = nn.Linear(self.hidden_size, self.hidden_size, bias=False) #第二个self.hidden_size可以*系数\n",
    "        self.Wk = nn.Linear(self.hidden_size, self.hidden_size, bias=False)\n",
    "        self.Wv = nn.Linear(self.hidden_size, self.hidden_size, bias=False)\n",
    "        self.Wo = nn.Linear(self.hidden_size, self.hidden_size, bias=False) # 输出层\n",
    "\n",
    "    def _split_heads(self, x: Tensor) -> Tensor:\n",
    "        bs, seq_len, _ = x.shape #假设输入的维度是[batch_size, seq_len, hidden_size],hidden_size是512\n",
    "        x = x.view(bs, seq_len, self.num_heads, self.head_dim) #num_heads是8，head_dim是64\n",
    "        return x.permute(0, 2, 1, 3) #变换维度，[batch_size, num_heads, seq_len, head_dim]\n",
    "\n",
    "    def _merge_heads(self, x: Tensor) -> Tensor:#将多头注意力的输出合并为一个张量\n",
    "        bs, _, seq_len, _ = x.shape #假设输入的维度是[batch_size, num_heads, seq_len, head_dim]\n",
    "        return x.permute(0, 2, 1, 3).reshape(bs, seq_len, self.hidden_size) # 变换维度，变为[batch_size, seq_len, hidden_size]\n",
    "\n",
    "    def forward(self, querys, keys, values, attn_mask=None) -> AttentionOutput:\n",
    "        # split heads\n",
    "        querys = self._split_heads(self.Wq(querys)) #(batch_size, seq_len,hidden_dim)-->[batch_size, num_heads, seq_len, head_dim]\n",
    "        keys = self._split_heads(self.Wk(keys))#[batch_size, num_heads, seq_len, head_dim]\n",
    "        values = self._split_heads(self.Wv(values))#[batch_size, num_heads, seq_len, head_dim]\n",
    "\n",
    "        # calculate attention scores\n",
    "        qk_logits = torch.matmul(querys, keys.mT) # 计算注意力分数，matmul是矩阵乘法，mT是矩阵转置,qk_logits是[batch_size, num_heads, seq_len, seq_len]\n",
    "        # print(querys.shape[-2], keys.shape[-2])  #3 4\n",
    "        if attn_mask is not None:\n",
    "            attn_mask = attn_mask[:, :, : querys.shape[-2], : keys.shape[-2]]\n",
    "            qk_logits += attn_mask * -1e9 # 给需要mask的地方设置一个负无穷\n",
    "        attn_scores = F.softmax(qk_logits / (self.head_dim**0.5), dim=-1) # 计算注意力分数\n",
    "\n",
    "        # apply attention scores\n",
    "        embeds = torch.matmul(attn_scores, values) # softmax后的结果与value相乘，得到新的表示\n",
    "        embeds = self.Wo(self._merge_heads(embeds)) # 输出层 [batch_size, seq_len, hidden_size]\n",
    "\n",
    "        return AttentionOutput(hidden_states=embeds, attn_scores=attn_scores)\n",
    "\n",
    "mha = MultiHeadAttention({\"num_heads\": 2, \"d_model\": 2})\n",
    "query = torch.randn(2, 3, 2) # [batch_size, seq_len, hidden_size]\n",
    "query /= query.norm(dim=-1, keepdim=True) # 归一化\n",
    "key_value = torch.randn(2, 4, 2)\n",
    "print(f'key_value.shape {key_value.shape}')\n",
    "outputs = mha(query, key_value, key_value) #最终输出shape和query的shape一样\n",
    "print(outputs.hidden_states.shape)\n",
    "print(outputs.attn_scores.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:24.816743500Z",
     "start_time": "2024-08-05T08:06:24.108022500Z"
    },
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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8v333xu25eTkKP7+/srgwYMN21avXq2o1Wpl7969Ro//4osvFEDZv3+/YVtmZmah5+nRo4dSuXJlw3/HxsYq9vb2Su/evRW9Xm/YPnv2bAUweo2Kcvfz5ObmKnXr1lU6d+5stN3FxcXk/j744AOTr/2VK1cUjUajvPfee0bbz549q2i1WqPtxX39jh49qgDKypUrC+Vx93H9/fffFUB59913jeKGDBmiqFQq5dKlS4ZtgGJvb2+07fTp0wqgLF26tNBz3V2/RqNRUlNTFUVRlE8//VSpUKGC0rx5c+W1115TFEVRdDqd4unpqbz00kuGx5k6t4p6jW/Fjhs3zmj7wIEDFR8fH8N/nzp1SgGU8ePHG8XNnDlTAZR///3XqGZT53yFChWMcli3bl2h99C9jB49WgGU+fPnG7bdes+qVCrl559/NmwPDg4ulEd2drai0+mM9hkeHq44ODgob7/9tmFb//79lTp16twzl1uvW1xcnBIUFKQEBAQozZo1UxITE4tViygZZKbi/7Hx48cb/r9Go6Fp06YoisKzzz5r2O7p6UmNGjUICwuzRYpFcnV15emnnzb8t729Pc2bNzfKc926ddSqVYuaNWsSHx9v+OncuTMAO3fuNMQ6OTkZ/n9KSgrx8fF06NCBsLAwwyfh7du3k5uby/PPP280lT59+vRi533n8yQlJZGSkkK7du04ceJE8Ys34bfffkOv1zNs2DCjWv39/alWrZpRrVC81+9+/PPPP2g0GsMn7VtefvllFEUxmkEC6Nq1K1WqVDH8d/369XF3d//P52/Xrh06nY4DBw4ABTMS7dq1o127duzduxeAc+fOkZycTLt27R6ollsmT55c6LkTEhJITU0FCmoGCs3EvPzyywBGs0+Wdud7+dZ71sXFhWHDhhm216hRA09PT6PX2MHBAbW64M+ATqcjISEBV1dXatSoYXROenp6EhkZydGjR/8zl3PnztGhQwcqVqzI9u3b8fLyMkeJ4jEhTcX/Y+XLlzf6bw8PDxwdHfH19S20PSkpyZqp/ady5coVWn/h5eVllOfFixc5f/48fn5+Rj/Vq1cHIDY21hC7f/9+unbtiouLC56envj5+TF79mwAQ1Nx9epVAKpVq2b0vH5+fsUeODdu3EjLli1xdHTE29vbcEno1nM8qIsXL6IoCtWqVStUb1BQkFGtULzX735c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",
      "text/plain": [
       "<Figure size 640x480 with 4 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# plt.subplots() 用于创建子图网格，其维度基于 outputs.attn_scores.shape[:2]。子图的行数和列数似乎由 outputs.attn_scores 的前两个维度确定。\n",
    "fig, axis = plt.subplots(*outputs.attn_scores.shape[:2])\n",
    "for i in range(query.shape[0]):\n",
    "    for j in range(outputs.attn_scores.shape[1]):\n",
    "        # axis[i, j].matshow(outputs.attn_scores[i, j].detach().numpy())：此行使用 Matplotlib 的 matshow 绘制每个 i 和 j 的注意力分数热图。detach().numpy() 将 PyTorch 张量转换为 NumPy 数组以进行可视化。\n",
    "        axis[i, j].matshow(outputs.attn_scores[i, j].detach().numpy())\n",
    "        for x in range(outputs.attn_scores.shape[2]):\n",
    "            for y in range(outputs.attn_scores.shape[3]):\n",
    "                # axis[i, j].text(y, x, f\"{outputs.attn_scores[i, j, x, y]:.2f}\", ha=\"center\", va=\"center\", color=\"w\")：此代码在热图上叠加文本，显示 (x, y) 位置处的注意力分数。格式化部分 f\"{outputs.attn_scores[i, j, x, y]:.2f}\" 确保以两位小数显示注意力分数。文本以白色居中显示在 (y, x) 坐标处。\n",
    "                axis[i, j].text(y, x, f\"{outputs.attn_scores[i, j, x, y]:.2f}\", ha=\"center\", va=\"center\", color=\"w\")\n",
    "fig.suptitle(\"multi head attention without mask\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:25.525550800Z",
     "start_time": "2024-08-05T08:06:24.814755500Z"
    },
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--------------------------------------------------\n"
     ]
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 4 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "print('-'*50)\n",
    "# mask\n",
    "mask = torch.Tensor([[0, 0, 1, 1], [0, 0, 0, 1], [0, 0, 0, 0]]).reshape(1, 1, 3, 4) #手工构造mask\n",
    "outputs_masked = mha(query, key_value, key_value, mask)\n",
    "\n",
    "fig, axis = plt.subplots(*outputs_masked.attn_scores.shape[:2])\n",
    "for i in range(query.shape[0]):\n",
    "    for j in range(outputs_masked.attn_scores.shape[1]):\n",
    "        axis[i, j].matshow(outputs_masked.attn_scores[i, j].detach().numpy())\n",
    "        for x in range(outputs_masked.attn_scores.shape[2]):\n",
    "            for y in range(outputs_masked.attn_scores.shape[3]):\n",
    "                axis[i, j].text(y, x, f\"{outputs_masked.attn_scores[i, j, x, y]:.2f}\", ha=\"center\", va=\"center\", color=\"w\")\n",
    "fig.suptitle(\"multi head attention with mask\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "GkzzrRWVN4yE"
   },
   "source": [
    "#### Transformer-Block"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:25.527550400Z",
     "start_time": "2024-08-05T08:06:25.524551200Z"
    },
    "id": "b16xpL47N4yE"
   },
   "outputs": [],
   "source": [
    "# 通过使用 @dataclass 装饰器，Python 会自动为该类生成一些方法，如 __init__()、__repr__() 和 __eq__() 等，这些方法可以使类的使用更加方便。\n",
    "@dataclass\n",
    "class TransformerBlockOutput:\n",
    "# hidden_states: Tensor：用于存储某个块产生的隐藏状态。\n",
    "# self_attn_scores: Tensor：包含了自注意力机制（self-attention）所计算得到的注意力分数。\n",
    "# cross_attn_scores: Optional[Tensor] = None：是一个可选字段，存储了交叉注意力（cross-attention）计算得到的注意力分数。这里的 Optional 表示这个字段可以是 Tensor 类型，也可以是 None。\n",
    "    hidden_states: Tensor\n",
    "    self_attn_scores: Tensor\n",
    "    cross_attn_scores: Optional[Tensor] = None\n",
    "\n",
    "class TransformerBlock(nn.Module):\n",
    "    def __init__(self, config, add_cross_attention=False):\n",
    "        super().__init__()\n",
    "        # hyper params\n",
    "        self.hidden_size = config[\"d_model\"]\n",
    "        self.num_heads = config[\"num_heads\"]\n",
    "        dropout_rate = config[\"dropout\"]\n",
    "        ffn_dim = config[\"dim_feedforward\"]\n",
    "        eps = config[\"layer_norm_eps\"] # 层归一化的epsilon值\n",
    "\n",
    "        # self-attention\n",
    "        self.self_atten = MultiHeadAttention(config) # 多头注意力\n",
    "        self.self_ln = nn.LayerNorm(self.hidden_size, eps=eps) #层归一化(层标准化)\n",
    "        self.self_dropout = nn.Dropout(dropout_rate)\n",
    "\n",
    "        # cross-attention，交叉注意力，decoder中使用,因此额外做一个判断\n",
    "        if add_cross_attention:\n",
    "            self.cross_atten = MultiHeadAttention(config)\n",
    "            self.cross_ln = nn.LayerNorm(self.hidden_size, eps=eps)\n",
    "            self.cross_dropout = nn.Dropout(dropout_rate)\n",
    "        else:\n",
    "            self.cross_atten = None\n",
    "\n",
    "        # FFN,前馈神经网络\n",
    "        self.ffn = nn.Sequential(\n",
    "            nn.Linear(self.hidden_size, ffn_dim),\n",
    "            nn.ReLU(),\n",
    "            nn.Linear(ffn_dim, self.hidden_size),\n",
    "        )\n",
    "        self.ffn_ln = nn.LayerNorm(self.hidden_size, eps=eps)\n",
    "        self.ffn_dropout = nn.Dropout(dropout_rate)\n",
    "\n",
    "    def forward(\n",
    "        self,\n",
    "        hidden_states,\n",
    "        attn_mask=None,\n",
    "        encoder_outputs=None,\n",
    "        cross_attn_mask=None,\n",
    "    ):\n",
    "        # self-attention,自注意力\n",
    "        self_atten_output = self.self_atten(\n",
    "            hidden_states, hidden_states, hidden_states, attn_mask\n",
    "        )\n",
    "        self_embeds = self.self_ln(\n",
    "            hidden_states + self.self_dropout(self_atten_output.hidden_states)\n",
    "        ) #多头注意力进行dropout，然后和原始输入进行残差连接，然后进行层归一化\n",
    "\n",
    "        # cross-attention，交叉注意力\n",
    "        if self.cross_atten is not None:\n",
    "            assert encoder_outputs is not None\n",
    "            cross_atten_output = self.cross_atten(\n",
    "                self_embeds, encoder_outputs, encoder_outputs, cross_attn_mask\n",
    "            ) #query是self_embeds，key和value都是encoder_outputs\n",
    "            cross_embeds = self.cross_ln(\n",
    "                self_embeds + self.cross_dropout(cross_atten_output.hidden_states)\n",
    "            ) # 交叉注意力进行dropout，然后和self_embeds进行残差连接，然后进行层归一化\n",
    "\n",
    "        # FFN\n",
    "        embeds = cross_embeds if self.cross_atten is not None else self_embeds # 如果有交叉注意力，则使用交叉注意力的输出作为FFN的输入；否则，使用self_embeds作为FFN的输入\n",
    "        ffn_output = self.ffn(embeds) # 前馈神经网络\n",
    "        embeds = self.ffn_ln(embeds + self.ffn_dropout(ffn_output)) # 前馈神经网络进行dropout，然后和原始输入进行残差连接，然后进行层归一化\n",
    "\n",
    "        return TransformerBlockOutput(\n",
    "            hidden_states=embeds,\n",
    "            self_attn_scores=self_atten_output.attn_scores,\n",
    "            cross_attn_scores=cross_atten_output.attn_scores\n",
    "            if self.cross_atten is not None\n",
    "            else None,\n",
    "        )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "tfJIGaohN4yE"
   },
   "source": [
    "#### Encoder"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:25.527550400Z",
     "start_time": "2024-08-05T08:06:25.525550800Z"
    },
    "id": "sTLabHm7N4yE"
   },
   "outputs": [],
   "source": [
    "from typing import List\n",
    "\n",
    "@dataclass\n",
    "class TransformerEncoderOutput:\n",
    "    last_hidden_states: Tensor\n",
    "    attn_scores: List[Tensor]\n",
    "\n",
    "# https://pytorch.org/docs/stable/generated/torch.nn.Module.html#torch.nn.Module\n",
    "class TransformerEncoder(nn.Module):\n",
    "    def __init__(self, config):\n",
    "        super().__init__()\n",
    "        # hyper params\n",
    "        self.num_layers = config[\"num_encoder_layers\"]\n",
    "\n",
    "        # layers,仅仅是一个模块的列表，它本身没有定义前向传递（forward pass）过程。你需要在 forward 方法中明确地定义如何使用这些模块。\n",
    "        self.layers = nn.ModuleList(\n",
    "            [TransformerBlock(config) for _ in range(self.num_layers)]\n",
    "        )\n",
    "\n",
    "    def forward(\n",
    "        self, encoder_inputs_embeds, attn_mask=None\n",
    "    ) -> TransformerEncoderOutput:\n",
    "        attn_scores = [] # 存储每个层的注意力分数\n",
    "        embeds = encoder_inputs_embeds # 输入的嵌入向量作为第一层的输入(embedding+位置编码)\n",
    "        for layer in self.layers:\n",
    "            block_outputs = layer(embeds, attn_mask=attn_mask)\n",
    "            embeds = block_outputs.hidden_states #上一层的输出作为下一层的输入\n",
    "            # 在每个层的输出中，提取了隐藏状态 block_outputs.hidden_states，并将对应的注意力分数 block_outputs.self_attn_scores 添加到列表 attn_scores 中。\n",
    "            attn_scores.append(block_outputs.self_attn_scores) # 存储每个层的注意力分数,用于画图\n",
    "\n",
    "        return TransformerEncoderOutput(\n",
    "            last_hidden_states=embeds, attn_scores=attn_scores\n",
    "        )\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "BEMNj6eBN4yE"
   },
   "source": [
    "#### Decoder"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:25.527550400Z",
     "start_time": "2024-08-05T08:06:25.525550800Z"
    },
    "id": "wCHOur-QN4yE"
   },
   "outputs": [],
   "source": [
    "@dataclass\n",
    "class TransformerDecoderOutput:\n",
    "    last_hidden_states: Tensor\n",
    "    self_attn_scores: List[Tensor]\n",
    "    cross_attn_scores: List[Tensor]\n",
    "\n",
    "\n",
    "class TransformerDecoder(nn.Module):\n",
    "    def __init__(self, config):\n",
    "        super().__init__()\n",
    "        # hyper params\n",
    "        self.num_layers = config[\"num_decoder_layers\"]\n",
    "\n",
    "        # layers\n",
    "        self.layers = nn.ModuleList(\n",
    "            [\n",
    "                TransformerBlock(config, add_cross_attention=True)\n",
    "                for _ in range(self.num_layers)\n",
    "            ]\n",
    "        )\n",
    "\n",
    "    def forward(\n",
    "        self,\n",
    "        decoder_inputs_embeds,\n",
    "        encoder_outputs,\n",
    "        attn_mask=None,\n",
    "        cross_attn_mask=None,\n",
    "    ) -> TransformerDecoderOutput:\n",
    "        self_attn_scores = [] # 存储每个层的自注意力分数\n",
    "        cross_attn_scores = [] # 存储每个层的交叉注意力分数\n",
    "        embeds = decoder_inputs_embeds # 输入的嵌入向量作为第一层的输入(embedding+位置编码)\n",
    "        for layer in self.layers:\n",
    "            block_outputs = layer(\n",
    "                embeds,\n",
    "                attn_mask=attn_mask, # 自注意力的mask\n",
    "                encoder_outputs=encoder_outputs,\n",
    "                cross_attn_mask=cross_attn_mask, # 交叉注意力的mask\n",
    "            )\n",
    "            embeds = block_outputs.hidden_states # 上一层的输出作为下一层的输入\n",
    "            self_attn_scores.append(block_outputs.self_attn_scores) # 存储每个层的自注意力分数\n",
    "            cross_attn_scores.append(block_outputs.cross_attn_scores) # 存储每个层的交叉注意力分数\n",
    "\n",
    "        return TransformerDecoderOutput(\n",
    "            last_hidden_states=embeds,\n",
    "            self_attn_scores=self_attn_scores,\n",
    "            cross_attn_scores=cross_attn_scores,\n",
    "        )\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "zPrvXAXtN4yF"
   },
   "source": [
    "#### mask\n",
    "\n",
    "- mask实际上大类上只有两种\n",
    "    1. `padding_mask`：mask掉`pad_idx`，不计算损失\n",
    "    2. `attention_mask`：mask掉`pad_idx`，不计算注意力分数\n",
    "- Decoder的`attention_mask`和Encoder有一定的区别：\n",
    "    - Encoder可以同时看见序列所有信息，故只mask掉`pad_idx`\n",
    "    - Decoder只能看到在自身之前的序列的信息，故要额外mask掉自身之后的序列"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:25.527550400Z",
     "start_time": "2024-08-05T08:06:25.526551200Z"
    },
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "D2N9VmcAWLn1",
    "outputId": "560b8af9-c854-4fd7-df3e-86e9eb9045cc"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[False,  True,  True,  True,  True],\n",
       "        [False, False,  True,  True,  True],\n",
       "        [False, False, False,  True,  True],\n",
       "        [False, False, False, False,  True],\n",
       "        [False, False, False, False, False]])"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(torch.triu(torch.ones(5, 5)) == 0).transpose(-1,-2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:26.193720900Z",
     "start_time": "2024-08-05T08:06:25.526551200Z"
    },
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 426
    },
    "id": "QxpSYOsaN4yF",
    "outputId": "1022d3c3-c72e-4798-b998-c71c6690b94e"
   },
   "outputs": [
    {
     "data": {
      "image/png": "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GVOmTNE4HL8mRt0ndvPmTYSEhKBfv37YtWsXWrRogbNnz8LZ2dnQoRERGS1DPTsxNjYWsbGxGt/LzMysUtajRw/8/PPPdb7Ow4w6iaWkpMDT0xNr1qxRlbVt29aAERERSYREnn2oK6NuTtyxYwcCAwPx4osvwsXFBd26dcOqVasMHRYRkVGrrInpukmBUSex8+fPY8WKFejQoQP27NmDN954A5MnT8a6deuqPaasrKzKDHMiIjJNRt2cqFQqERgYiHnz5gEAunXrhhMnTiA9PR1RUVEaj0lOTsYHH3zQkGESERkXLsViHNzd3dG5c2e1sscffxyXLl2q9piEhAQUFxertry8vEcdJhGRkZHpaTN+Rl0TCwkJwenTp9XKzpw5gzZt2lR7jFwu19tjUYiIyLgZdU3srbfews8//4x58+bh3Llz2LhxI1auXFnnyXBERGbFAJOdDcWok1j37t2xbds2fP755/D19cWHH36ItLQ0jB071tChEREZLzNKYkbdnAgAQ4YMwZAhQwwdBhERGaF61cTy8vJw+fJl1eusrCzExcVh5cqVeguMiIjqqXIpFl03CahXEhszZgz2798PAMjPz8czzzyDrKwsvPfee5g9e7ZeAyQiorpp6KfYG1K9mhNPnDiBoKAgAMAXX3wBX19f/Pjjj/juu+8wceJEzJw5U69BEumDvlaIBrhKNJGxqFcSq6ioUA1j37dvH5577jkAQKdOndSeUkxERAbAyc418/HxQXp6Og4ePIi9e/di4MCBAICrV6+iWbNmeg2QiIjqiH1iNUtJScEnn3yCvn37YvTo0fDz8wPw4IG9lc2MREREj1q9mhP79u2LoqIilJSUqK3t9dprr6Fx48Z6C46IiOpOJh5sup5DCupVE0tKSsLly5erLE7p5eUFFxcXvQRGRET1ZEaTneuVxL766it4e3ujf//+2LhxI8rKyvQdFxER1Rf7xGqWk5ODI0eOwMfHB1OmTIGbmxveeOMNHDlyRN/xERERVavez07s1q0bPvroI1y9ehWffvopLl++jJCQEHTt2hVLlixBcXGxPuMkIiJtsTlRe0IIVFRUoLy8HEIIODs7Y+nSpfD09MTmzZv1ESMREdUFk1jtjh07htjYWLi7u+Ott95Ct27dcPLkSfzwww84e/Ys5s6di8mTJ+szViIiIjX1SmJdunTBk08+idzc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",
      "text/plain": [
       "<Figure size 480x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\n",
    "def generate_square_subsequent_mask(sz: int) -> Tensor:\n",
    "    \"\"\"\n",
    "    Generate a square mask for the sequence. The masked positions are filled with True.\n",
    "        Unmasked positions are filled with False.\n",
    "    \"\"\"\n",
    "    # torch.ones(sz, sz): 创建一个全为 1 的 sz × sz 的矩阵。\n",
    "    # torch.triu(...): 使用 triu 函数取得矩阵的上三角部分，将主对角线以下部分置零。\n",
    "    mask = (torch.triu(torch.ones(sz, sz)) == 0).transpose(-1, -2).bool()\n",
    "    # mask = torch.triu(torch.ones(sz, sz))\n",
    "    return mask\n",
    "\n",
    "\n",
    "plt.matshow(generate_square_subsequent_mask(16))\n",
    "plt.colorbar()\n",
    "plt.xlabel(\"keys\")\n",
    "plt.ylabel(\"querys\")\n",
    "plt.title(\"1 means mask while 0 means unmask\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:27.178084Z",
     "start_time": "2024-08-05T08:06:25.538543600Z"
    },
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 960
    },
    "id": "cPeMjXO1N4yF",
    "outputId": "e6922ce8-ba71-491f-d7a6-709a14a4b7d7"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['[BOS]', '[UNK]', '[UNK]', 'brown', '[UNK]', 'jumps', 'over', 'the', '[UNK]', 'dog', '.', '[EOS]']\n"
     ]
    },
    {
     "data": {
      "image/png": "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rFn64x//qDFjxuiFF17QNddcIw8PD02ePNlpPzt27Kh9+/bpk08+0b/+9S/9/e9/15tvvqnnnntOM2fOdNr+b37zG7333ntKTk7WI488YmpfAKAu8/Hx0d133601a9boX//6l+69917T23j88ce1ePFiTZ48Wb/61a9ks9lksViUkJBQYf+50mt92XOWLl2q4ODgcut5ef3yv5au6H0VoY/BVQhSqJeuu+46PfbYY3rsscf0448/qnv37vrTn/6kV155RZJktVp11113uaSW06dPKy0tTTNnztRzzz3nGC97V+9Cl/sE97rw6e4ffvih7rjjDr399ttO42fOnCl3Ua2fn5/i4+MVHx+vwsJC3X///frTn/6kqVOnOp3yMnfuXHl5eemxxx5T06ZNL3kRLwC4yw033CBJ2rdvn9q0aeMYLyws1KFDhxz95sL17rzzTqdt7Nu3z/F4GYvFouTkZA0aNEhDhgzR2rVrFRMTY6q2Dz/8UCNHjtS8efMcY/n5+RXeTbAyym501Lx588v20cr2vqCgIPn6+lbYE/ft21elGq8GfQxmcGof6pWSkpJypyo0b95cISEhKigoUHh4uNq2bauXXnqpwlvHVnSL16tV9g7YxUeGXn311XLr+vn5SVKFDc7Pz6/Kjc9VPD09y+3n3/72t3K39b341reNGjXSzTffLMMwVFRU5PSYxWLRwoUL9dvf/lYjR47Uxx9/XDPFA0AV3XXXXWrUqJFee+01p9fAt99+W7m5ubrnnnskST169FDz5s21YMECFRQUONZbu3at9uzZ41jvQo0aNdKqVasUERGhgQMHatu2baZqq+h1+fXXX1dJSYmp7ZSJjY2V1WrVrFmzyr1eS7/00cr2Pk9PT8XGxuqjjz7S999/7xjfs2ePUlJSqlTj1aCPwQyOSKFeycvLU2hoqH7729/q1ltvlb+/v9atW6ft27dr3rx58vDw0KJFixQXF6dOnTpp9OjRatmypY4ePar169fLarXqH//4R7XWZLVaHbdgLSoqUsuWLZWamqpDhw6VWzc8PFySNG3aNCUkJMjb21sDBw6Un5+fwsPDtW7dOr388ssKCQlR69at1bNnz2qt9Wrde++9ev755zV69Gjdfvvt2r17t5KTk53eoZWk/v37Kzg4WL1791aLFi20Z88evfHGG7rnnnvUtGnTctv18PDQsmXLNHjwYA0dOlSffvppuXdzAcBdgoKCNHXqVM2cOVMDBgzQr3/9a+3bt09vvvmmIiIiNHz4cEmSt7e3Zs+erdGjRys6OloPPPCA4/bnrVq10hNPPFHh9n19ffXJJ5/ozjvvVFxcnDZs2KBbbrmlUrXde++9Wrp0qWw2m26++WZt2bJF69atU7Nmzaq0r1arVfPnz9dDDz2k7t27KyEhQUFBQfr+++/1z3/+U71799Ybb7xhqvfNnDlT//rXvxQZGanHHntMxcXFjs9o2rVrV5XqrCr6GExxz80CgZpRUFBgPPnkk8att95qNG3a1PDz8zNuvfVW480333Rab+fOncb9999vNGvWzPDx8TFuuOEGY+jQoUZaWppjneq8/Xl2drZx3333GQEBAYbNZjOGDBli5OTklLvtqmEYxgsvvGC0bNnS8PDwcJp/7969RlRUlOHr62tIctwK/cLbq16oovqv5FL7Fx0dXeFtXm+44QbjnnvucXyfn59vTJkyxbjuuusMX19fo3fv3saWLVuM6OhoIzo62rHeW2+9ZURFRTl+/m3btjWefPJJIzc317FORft1/vx5Izo62vD39ze2bt1a6f0CgOpW0WvsG2+8Ydx0002Gt7e30aJFC2P8+PHG6dOnyz13xYoVRrdu3QwfHx/jmmuuMR588EEjOzvbaZ2KXo9PnDhh3HzzzUZwcLCxf//+StV5+vRpY/To0ca1115r+Pv7G7GxscbevXuNG264wekjNcr2Z/v27U7PX79+vSHJWL9+fbnx2NhYw2azGY0bNzbatm1rjBo1ytixY4djHTO9b8OGDUZ4eLjRqFEjo02bNsaCBQscfcAM+hhcyWIYJq9EBwAAAIAGjmukAAAAAMAkrpECrkJubq5++umny65T0e1hXa2u1AkAqJyzZ89WeNOkCwUFBV3ylt91DX0MtRGn9gFXYdSoUXrvvfcuu05t+CdWV+oEAFTOjBkzyn1e0cUOHTqkVq1auaagGkYfQ21EkAKuwrfffqucnJzLruOqz6u6nLpSJwCgcg4ePKiDBw9edp0+ffo4fZ5RXUYfQ21EkAIAAAAAk7jZBAAAAACYRJACAAAAAJMIUnCp9PR0JSYmursMl8jMzNT8+fPdXYbbHD58WKmpqZKkHj16uLka1/j66681atQod5cBwCR6U8NBb0J1IkhVID09XWFhYVq4cKFiYmIUGRmpqKgoDRs2TCUlJZKk3bt3q2/fvoqOjta9996rrKwsSdKuXbsUFRWl6Oho3X777Tp69Ki+/fZbde3a9bIv0hfOefE/7LLvR40apbi4uHLjFzaALVu2qHfv3jpz5oxGjBih0NDQWjXn5ZSWllbpeZXhjn3t2rWrxo8fX9274lJX8zu5sFnVhNr291sfVfRaGBMTo5iYGOXm5qq0tFTPPvusIiMj1adPH7322muO5yYmJqp3797q06ePXnjhBUnSU089pYCAgCveshnluaMvXTwvvan60Zuqht7UsNWm3kSQuoT4+HiNGzdOkrR27VplZGTI399fW7ZsUVFRkYYPH66FCxdqw4YNmjp1qoYPHy5JeuGFFzR//nxt2LBBaWlpatasmW6++Wa9+uqrpua8lOzsbO3atavCx3bv3q1JkyZp1apVCggI0JIlS674mQrumHPXrl0aOHCgIiIitHv3bnXv3l2TJk3SQw89pOzsbN11112KiorSxIkTJUkPPvigcnJylJaWprZt20qSZs6cqfXr12vGjBl66KGHdPfddys6OvqynzHh6n0te0G88IW07OsZM2Zo+PDhiouLU1xcnObPn6+YmBjFx8dLkt59910NHjxYd999tyIjI3X06FGdOnVKMTExuuOOOzRo0KDL7ocklZSUaPjw4YqOjtY999yjuXPnasWKFZKk7777Tg888IAkadasWYqOjlZUVJR2794tSU6/k6qaP3++VqxYoZiYGJ07d04jR45U165dlZycLOnnO07FxsYqJiZGTzzxRJXmcMff78WKi4s1dOhQ3XXXXXrllVckScuXL1fPnj3Vq1cvpaSkSJJSU1PVrVs3DRkyRFFRUTp8+LCpedzl4tfC9PR0paeny2az6e2339apU6e0ceNGpaenKyUlRevWrdM333yjI0eOaPPmzdq0aZPj3/KcOXPUtWtXN+5N3eaOvnTxvJdCb6I30Zt+QW+qebWlNxGkTMjLy5PVatXWrVvVtWtXxwtn7969VVpaqqysLPn6+mrdunU6d+6cfH19q/22o4mJiZozZ0658UOHDmnMmDFauXKlWrRoUavnPH/+vD7++GMtWbJE06ZN0+nTp/X4448rOTlZf/7zn5WYmKiMjAz99NNPysjIUJ8+fbRx40Zt3LhRHTp00NGjR/Xll1+qV69ekqT27dvr008/Va9evfTZZ5/Vqn29nI4dO2rt2rUKDAxUYWGh0tPTVVhY6LidbZMmTfTpp59q2rRpmj17tnbu3KnbbrtN69ev1+rVq6+4/dWrVys0NFQbNmxQQkKCzp8/r5UrV0qSVqxYofj4eH399dfat2+fNmzYoOXLl+vZZ5+VJKffSVWNHz9e8fHxSk9P17Fjx/T6668rIyPD8c7QM888ozfffFPp6enKz8/Xjh07qjzX5dT07/Sjjz5Su3bttG7dOkVERKikpERJSUnasGGDUlNTNW3aNEnSc889p7S0NC1btsxxpKCuW758uZ588klJkpeXl/7whz/ogw8+UOPGjbV//37t2bNHkhQYGOjOMuu12tCXJHoTvYneZBa9qea4sjcRpCohLi5O3bp1U3Z2tjp27KicnByFhIQ4rRMaGqqcnBzNnTtXe/bs0a233qr4+HidO3euWmsJDw/XiRMndOTIEafxtLQ09ezZs0Y+eK+65+zWrZssFos6duyo//3vfwoMDFS7du0kSQcOHFBERIQkKSIiQvv371dkZKQyMjK0b98+jR07VmlpaSouLpavr69je5IUFham06dP16p9vdiFnzbQpUsXSVJISIjj65YtWzr2ITw8XNIvP4fo6Gj5+fnpwQcf1Msvv3zFuS7+WR44cEC5ubmy2+1KSUlRXFycvv32W33xxReKiYnRsGHDHIe1L/ydVIc2bdrIarXKarU6TkPau3evxo4dq5iYGG3btk3Z2dnVNt+Favp3euDAAaff1fHjx3X99dercePGslqt8vb2VnFxsUpKSnTNNdfIx8dHt9xyy1XN6S5xcXGKiYlxnJJy8Wth2etg27Zt9cwzz+ixxx7TjTfeqDVr1rir5HqrNvUlid5Eb6I3mUVvqj7u7E0EqUpYu3atdu7cqSFDhmjevHm67rrryn0oXHZ2tkJCQtSiRQstWLBABw4cUPv27bV06VLT81ksFsfX+fn5jhflMlOmTNG8efOcxsaMGaOjR4/qnXfeMT2fq+fMzMyUYRjat2+frrvuOnl4/PJn2K5dO23btk2StH37drVv316dOnVSZmamGjVqpKioKL322mvq3r17hbVX5mPRXP3z9fT0VF5envLy8pw+PPHCOirah507d0qSduzYoXbt2qmoqEjTp09XcnKyUlNT9f3331923op+loMHD9bs2bPVpk0b+fj46KabblJ0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",
      "text/plain": [
       "<Figure size 1000x500 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--------------------------------------------------\n",
      "['[BOS]', '[UNK]', 'does', 'the', '[UNK]', 'say', '?', '[EOS]', '[PAD]', '[PAD]', '[PAD]', '[PAD]']\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1AAAAG1CAYAAAD3DRUpAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAABHu0lEQVR4nO3de1xUdf7H8TeIAoIzWOGFIFMzzTItvP1UZMTk0mUp826rqJub2oalbvro4q0kI9MuW8q6aRc3M6XazUi84SUtbVPRTV3LSyBamgreQC7n98c+mGUC8YA4M8Dr+XjMY5kzZ76fz2GFdx/OzBkPwzAMAQAAAACuyNPVDQAAAABAdcEABQAAAAAmMUABAAAAgEkMUAAAAABgEgMUAAAAAJjEAAUAAAAAJjFAAQAAAIBJDFAAAAAAYBIDFAAAAACYxAAFlGHx4sXy8PDQ4cOHHbYnJiaqRYsWqlOnjjp06OCS3mqDadOmycPDQydPnnR1KwBQyuUyoqrExcXJ39//mqxdluLj+fbbb51W80qKc6C6IsdqNgYowKTU1FT9+c9/Vvfu3bVo0SLNmjWrStffsmWLpk2bpjNnzpR6bNasWfr000+rtB4AAAAqjgEKMGndunXy9PTU3/72Nw0bNkz33ntvla6/ZcsWTZ8+nQEKAADAjTFAASb98ssv8vX1Vb169VzdCgAAAFyEAQo1ytmzZzV+/HjdfPPN8vb2VqNGjdSnTx9999139n2++eYbRUdHy2q1qn79+goPD9dXX31V7roeHh5atGiRzp8/Lw8PD3l4eGjx4sWmekpPT1dcXJxatGghHx8fNWnSRCNHjtSvv/5q32fatGmaNGmSJKl58+b2GocPH5aHh4fOnz+vd9991749Li7O/jwPDw/98MMPiouLU0BAgKxWq0aMGKELFy5U6HtX/Jr7n376Sffff7/8/f1144036i9/+Yskaffu3YqIiJCfn5+aNWumv//97w7PP3XqlCZOnKh27drJ399fFotFMTEx2rVrV6lab7zxhm6//XbVr19fDRs2VMeOHUut91tHjhzRLbfcojvuuEM///xzhY4NAK61t956S7fffru8vb0VFBSkcePGlfmKgo8//lihoaHy9fXVDTfcoEceeURHjx694vo7d+5UYGCgbDabzp07Z6qnI0eOaOzYsWrdurV8fX11/fXXq3///pd971ZeXp6eeuopBQYGys/PTw899JBOnDhRar+UlBSFhYXJz89PDRo00H333ad///vfDvuYyb5imzdvVqdOneTj46OWLVtqwYIFpo7vt8gxOIuXqxsAqtJjjz2m5cuX6/HHH1fbtm3166+/avPmzdq7d6/uvvturVu3TjExMQoNDdXUqVPl6empRYsWKSIiQps2bVLnzp3LXPf9999XUlKStm3bpoULF0qSunXrZqqn1atX6+DBgxoxYoSaNGmif//730pKStK///1vff311/Lw8FDfvn31n//8Rx9++KHmzp2rG264QZIUGBio999/X3/4wx/UuXNnjR49WpLUsmVLhxoDBgxQ8+bNlZCQoO+++04LFy5Uo0aNNHv27Ap9/woLCxUTE6OePXvq5Zdf1pIlS/T444/Lz89PzzzzjIYOHaq+fftq/vz5GjZsmP7v//5PzZs3lyQdPHhQn376qfr376/mzZvr559/1oIFCxQeHq7vv/9eQUFBkqS//vWveuKJJ9SvXz/Fx8crNzdX6enp+uabbzRkyJAy+/rxxx8VERGh6667TqtXr7Z/fwDAHUybNk3Tp0/XPffcozFjxmj//v16++23tX37dn311VeqW7eupP9erGHEiBHq1KmTEhIS9PPPP+u1117TV199pR07diggIKDM9bdv366oqCh17NhRn332mXx9fU31tX37dm3ZskWDBg1ScHCwDh8+rLfffls2m03ff/+96tev77D/n/70JzVs2FBTp07V4cOHNW/ePD3++OP66KOP7Pu8//77Gj58uKKiojR79mxduHBBb7/9tnr06KEdO3bo5ptvlmQu+6T/DjWRkZEKDAzUtGnTVFBQoKlTp6px48YV/H/hv8gxOIUB1CBWq9UYN25cmY8VFRUZrVq1MqKiooyioiL79gsXLhjNmzc3+vTpY9+2aNEiQ5Jx6NAh+7bhw4cbfn5+Fe7pwoULpbZ9+OGHhiRj48aN9m2JiYmlahbz8/Mzhg8fXmr71KlTDUnGyJEjHbY/9NBDxvXXX1+hPocPH25IMmbNmmXfdvr0acPX19fw8PAwli5dat++b98+Q5IxdepU+7bc3FyjsLDQYc1Dhw4Z3t7exowZM+zbYmNjjdtvv73cXoqP68SJE8bevXuNoKAgo1OnTsapU6cqdEwAcC2UzIhffvnFqFevnhEZGenwO/DNN980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9cEHH+jBBx/UgAED9MUXX5T66y0AuEpgYKCmTJmi6dOnKzo6Wr/73e+0f/9+vfXWW+rUqZMeeeQRSVLdunU1e/ZsjRgxQuHh4Ro8eLD9MuY333yznnzyyTLX9/X11eeff66IiAjFxMRow4YNuuOOO0z1dv/99+v999+X1WpV27ZttXXrVq1Zs0bXX399pY7VYrHo7bff1u9//3vdfffdGjRokAIDA/XTTz9p5cqV6t69u958880KZd/06dP15ZdfKiwsTGPHjlVBQYH9M5bS09Mr1WdlkWMwzTUX/wOqXl5enjFp0iSjffv2RoMGDQw/Pz+jffv2xltvveWw344dO4y+ffsa119/veHt7W00a9bMGDBggLF27Vr7PlV5GfPMzEzjoYceMgICAgyr1Wr079/fyMrKKnX5VMMwjJkzZxo33nij4enp6VB/3759Rs+ePQ1fX19Dkv2S5iUvk1pSWf1fyeWOLzw8vMzLtTZr1sy477777Pdzc3ONCRMmGE2bNjV8fX2N7t27G1u3bjXCw8ON8PBw+34LFiwwevbsaf/+t2zZ0pg0aZKRnZ1t36es47pw4YIRHh5u+Pv7G19//bXp4wKAqlbW79g333zTaNOmjVG3bl2jcePGxpgxY4zTp0+Xeu5HH31k3HXXXYa3t7dx3XXXGUOHDjUyMzMd9inr9/HJkyeNtm3bGk2aNDEOHDhgqs/Tp08bI0aMMG644QbD39/fiIqKMvbt22c0a9bM4aMxio9n+/btDs9fv369IclYv359qe1RUVGG1Wo1fHx8jJYtWxpxcXHGt99+a9+nItm3YcMGIzQ01KhXr57RokULY/78+fYcqAhyDM7iYRgVfJc5AAAAANRSvAcKAAAAAEziPVBAJWVnZ+vixYvl7lPWZV6drbr0CQAw59y5c2VeDKmkwMDAy166u7ohx+BueAkfUElxcXF69913y93HHX68qkufAABzpk2bVurzhn7r0KFDuvnmm53T0DVGjsHdMEABlfT9998rKyur3H2c9XlT5akufQIAzDl48KAOHjxY7j49evRw+Dyi6owcg7thgAIAAAAAk7iIBAAAAACYxAAFAAAAACYxQMFuz549iouLc2rNw4cPKzU1VZLUsWNHp9aurb755ht1795dd999tz744ANXtwMAl+WKXJLIJlcgm1CdMECVkJaWppCQECUlJclmsyksLEw9e/bUkCFDVFhYKEnavXu3evfurfDwcN1///3KyMiQJKWnp6tnz54KDw9Xt27ddPToUX3//ffq0KGDJk6caKrmb39JF9+Pi4tTTExMqe1paWn2tbdu3aru3bvrzJkzGjZsmIKDg6vuG3MNlQypa6G2f3/L0rRpU61bt05btmzRa6+9dtXrlfVzY7PZZLPZlJ2draKiIj377LMKCwtTjx499Prrr9ufO3HiRHXv3l09evTQzJkzJUl//vOfFRAQUO4lesuq2blzZ/saktStWzfNmDHDfn/x4sVq1aqVIiIiFBYWpgULFtgfi4yMNPUfSa6oW1tq4vLIJucjm5yPbCKb3LHmZRmwW79+vTFhwgTDMAwjPDzcOHv2rGEYhvHoo48amzZtMi5dumTceeedxg8//GAYhmFs3rzZ6Nmzp2EYhtGvXz9jz549hmEYxoULF4yLFy+WWvNKNUNDQx0eK74/fPhw44477jB27drlsL34uenp6UanTp2M48ePl3ruleTn5xv9+/c3evfubYwcOdIYPny48eGHHxqdO3c2unTpYnz55ZeGYRjG9u3bDZvNZvTo0cNITEw0DMMw3n77baNTp05Gr169jOTkZFP1fmvAgAFGcHCwER4ebrRp08YYNmyY0b59e+ODDz4wDMMwfvzxRyMyMtIIDw83xo8fX+H1Xf39LWnr1q1G586dDZvNZkydOtV48sknjZ49exqdOnUyduzYYfzyyy/Gvffea98/IiLCyM7OrnAdszZs2GAMHTr0qte53M9NsaSkJGPMmDGGYfz339u9995rrF692tizZ4/Rr18/+36nTp2yf13WOleqmZ+fb9x5551GRkaG8dNPPxn9+/c3evXqZX/OokWLjDfeeMMwDMM4f/68ERkZaXz++ef2x838f+qKurWlJi6vtmWTq3PJMGpPNrlbLhkG2UQ2uVfNy+EMlAlnz56VxWLR119/rQ4dOqhly5aSpO7du6uoqEgZGRny9fXVmjVrdP78efn6+lb5pUMnTpyol19+udT2Q4cOaeTIkVq2bJkaN25c4XU//fRT3XLLLVqzZo06deqkwsJCJSQkaMOGDUpNTdUzzzwjSZo8ebKSk5O1adMmbdiwQT///LOWLVumNWvWaN26dYqNja3UcY0ZM0YDBw5UWlqajh8/rjfeeEMbN260/yVo8uTJeuutt5SW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",
      "text/plain": [
       "<Figure size 1000x500 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "#通过下面代码查看mask的效果\n",
    "inputs_words = [\"The quick brown fox jumps over the lazy dog .\", \"What does the fox say ?\"]\n",
    "\n",
    "inputs_ids, input_mask =trg_tokenizer.encode([w.split() for w in inputs_words], return_mask=True)\n",
    "for i in range(len(inputs_words)):\n",
    "    decode_text = trg_tokenizer.decode(inputs_ids[i: i+1].tolist(), remove_bos=False, remove_eos=False, remove_pad=False, split=True)[0]\n",
    "    print(decode_text)\n",
    "    self_attn_mask  = input_mask[i].reshape(1, -1).repeat_interleave(inputs_ids.shape[-1], dim=0)\n",
    "    look_ahead_mask = generate_square_subsequent_mask(inputs_ids.shape[-1])\n",
    "\n",
    "    fig, axs = plt.subplots(1, 2, figsize=(10, 5))\n",
    "    axs[0].matshow(self_attn_mask)\n",
    "    axs[0].set_title(\"self_attn_mask\")\n",
    "    axs[0].set_yticks(range(len(decode_text)), decode_text, fontsize=6)\n",
    "    axs[0].set_ylabel(\"querys\")\n",
    "    axs[0].set_xticks(range(len(decode_text)), decode_text, fontsize=6)\n",
    "    axs[0].set_xlabel(\"keys\")\n",
    "    axs[1].matshow(look_ahead_mask)\n",
    "    axs[1].set_title(\"look_ahead_mask\")\n",
    "    axs[1].set_yticks(range(len(decode_text)), decode_text, fontsize=6)\n",
    "    axs[1].set_ylabel(\"querys\")\n",
    "    axs[1].set_xticks(range(len(decode_text)), decode_text, fontsize=6)\n",
    "    axs[1].set_xlabel(\"keys\")\n",
    "    plt.show()\n",
    "    print('-'*50)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:27.179078300Z",
     "start_time": "2024-08-05T08:06:26.513547400Z"
    },
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[False,  True,  True,  True,  True],\n",
       "        [False, False,  True,  True,  True],\n",
       "        [False, False, False,  True,  True],\n",
       "        [False, False, False, False,  True],\n",
       "        [False, False, False, False, False]])"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(torch.triu(torch.ones(5, 5)) == 0).transpose(-1, -2).bool()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:27.234057200Z",
     "start_time": "2024-08-05T08:06:27.159090100Z"
    },
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([5, 1, 4, 4])"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#帮我随机两个[5, 1, 1, 4]与[1, 1, 4, 4]尺寸的张量，并求和\n",
    "a = torch.randn(5, 1, 1, 4)\n",
    "b = torch.randn(1, 1, 4, 4)\n",
    "(a + b).shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "TelCDOoEN4yF"
   },
   "source": [
    "#### Transformer Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:27.234057200Z",
     "start_time": "2024-08-05T08:06:27.160089800Z"
    },
    "id": "oFGNt8FPN4yF"
   },
   "outputs": [],
   "source": [
    "@dataclass\n",
    "class TransformerOutput:\n",
    "    logits: Tensor\n",
    "    encoder_last_hidden_states: Tensor\n",
    "    encoder_attn_scores: List[Tensor] #画图\n",
    "    decoder_last_hidden_states: Tensor\n",
    "    decoder_self_attn_scores: List[Tensor] #画图\n",
    "    decoder_cross_attn_scores: List[Tensor] #画图\n",
    "    preds: Optional[Tensor] = None\n",
    "\n",
    "class TransformerModel(nn.Module):\n",
    "    def __init__(self, config):\n",
    "        super().__init__()\n",
    "        # hyper params\n",
    "        self.hidden_size = config[\"d_model\"]\n",
    "        self.num_encoder_layers = config[\"num_encoder_layers\"]\n",
    "        self.num_decoder_layers = config[\"num_decoder_layers\"]\n",
    "        self.pad_idx = config[\"pad_idx\"]\n",
    "        self.bos_idx = config[\"bos_idx\"]\n",
    "        self.eos_idx = config[\"eos_idx\"]\n",
    "        self.vocab_size = config[\"vocab_size\"]\n",
    "        self.dropout_rate = config[\"dropout\"]\n",
    "        self.max_length = config[\"max_length\"]\n",
    "        self.share = config[\"share_embedding\"]\n",
    "\n",
    "        # layers\n",
    "        self.src_embedding = TransformerEmbedding(config) # 输入的嵌入层\n",
    "        if self.share:#如果共享词嵌入，则使用src_embedding作为trg_embedding\n",
    "            self.trg_embedding = self.src_embedding #源和目标的嵌入层相同，共享参数，节省内存\n",
    "            self.linear = lambda x: torch.matmul(\n",
    "                x, self.trg_embedding.get_word_embedding_weights().T\n",
    "            ) # 输出层，共享参数，直接拿原有embedding矩阵的转置，节省内存\n",
    "        else:\n",
    "            self.trg_embedding = TransformerEmbedding(config) #decoder模块的嵌入层\n",
    "            self.linear = nn.Linear(self.hidden_size, self.vocab_size) # 输出层\n",
    "\n",
    "        self.encoder = TransformerEncoder(config)\n",
    "        self.decoder = TransformerDecoder(config)\n",
    "\n",
    "        # init weights\n",
    "        self._init_weights()\n",
    "\n",
    "    def _init_weights(self):\n",
    "        \"\"\"使用 xavier 均匀分布来初始化权重\"\"\"\n",
    "        for p in self.parameters():\n",
    "            if p.dim() > 1:\n",
    "                nn.init.xavier_uniform_(p)\n",
    "\n",
    "    def generate_square_subsequent_mask(self, sz: int) -> Tensor:\n",
    "        \"\"\"\n",
    "        Generate a square mask for the sequence. The masked positions are filled with True.\n",
    "            Unmasked positions are filled with False.为了生成斜三角的mask\n",
    "        \"\"\"\n",
    "        mask = (torch.triu(torch.ones(sz, sz)) == 0).transpose(-1, -2).bool()\n",
    "\n",
    "        return mask\n",
    "\n",
    "    def forward(\n",
    "        self, encoder_inputs, decoder_inputs, encoder_inputs_mask=None\n",
    "    ) -> TransformerOutput:\n",
    "        # encoder_inputs: [batch_size, src_len]\n",
    "        # decoder_inputs: [batch_size, trg_len]\n",
    "        # encoder_inputs_mask: [batch_size, src_len]\n",
    "        if encoder_inputs_mask is None:\n",
    "            encoder_inputs_mask = encoder_inputs.eq(self.pad_idx) # [batch_size, src_len]\n",
    "        encoder_inputs_mask = encoder_inputs_mask.unsqueeze(1).unsqueeze(\n",
    "            2\n",
    "        )  # [batch_size, 1, 1, src_len],用于encoder的自注意力\n",
    "        look_ahead_mask = self.generate_square_subsequent_mask(decoder_inputs.shape[1])\n",
    "        look_ahead_mask = (\n",
    "            look_ahead_mask.unsqueeze(0).unsqueeze(0).to(decoder_inputs.device)\n",
    "        )  #[trg_len, trg_len]--> [1, 1, trg_len, trg_len],用于decoder的自注意力\n",
    "        #增加decoder_inputs_mask和look_ahead_mask进行组合\n",
    "        decoder_inputs_mask = decoder_inputs.eq(self.pad_idx) # [batch_size, trg_len]，和上面encoder_inputs_mask一致\n",
    "        # print(decoder_inputs_mask.shape)\n",
    "        decoder_inputs_mask = decoder_inputs_mask.unsqueeze(1).unsqueeze(2)  # [batch_size, 1, 1, trg_len]\n",
    "        # print(decoder_inputs_mask.shape)\n",
    "        decoder_inputs_mask = decoder_inputs_mask + look_ahead_mask # [batch_size, 1, 1, trg_len]与[1, 1, trg_len, trg_len]相加，得到decoder的自注意力mask\n",
    "\n",
    "        # encoding\n",
    "        encoder_inputs_embeds = self.src_embedding(encoder_inputs)\n",
    "        encoder_outputs = self.encoder(encoder_inputs_embeds, encoder_inputs_mask) #encoder_inputs_mask用于encoder的自注意力,广播去做计算\n",
    "\n",
    "        # decoding\n",
    "        decoder_inputs_embeds = self.trg_embedding(decoder_inputs)\n",
    "        decoder_outputs = self.decoder(\n",
    "            decoder_inputs_embeds=decoder_inputs_embeds,\n",
    "            encoder_outputs=encoder_outputs.last_hidden_states,\n",
    "            attn_mask=decoder_inputs_mask, #用于decoder的自注意力,广播去做计算\n",
    "            cross_attn_mask=encoder_inputs_mask,#用于decoder的交叉注意力,广播去做计算\n",
    "        )\n",
    "\n",
    "        logits = self.linear(decoder_outputs.last_hidden_states) # [batch_size, trg_len, vocab_size]\n",
    "\n",
    "        return TransformerOutput(\n",
    "            logits=logits,\n",
    "            encoder_last_hidden_states=encoder_outputs.last_hidden_states,\n",
    "            encoder_attn_scores=encoder_outputs.attn_scores,\n",
    "            decoder_last_hidden_states=decoder_outputs.last_hidden_states,\n",
    "            decoder_self_attn_scores=decoder_outputs.self_attn_scores,\n",
    "            decoder_cross_attn_scores=decoder_outputs.cross_attn_scores,\n",
    "        )\n",
    "\n",
    "    @torch.no_grad()\n",
    "    def infer(self, encoder_inputs, encoder_inputs_mask=None) -> Tensor:\n",
    "        # assert len(encoder_inputs.shape) == 2 and encoder_inputs.shape[0] == 1\n",
    "        if encoder_inputs_mask is None:#应对多个样本同时进行推理\n",
    "            encoder_inputs_mask = encoder_inputs.eq(self.pad_idx)\n",
    "        encoder_inputs_mask = encoder_inputs_mask.unsqueeze(1).unsqueeze(2)  # [batch_size, 1, 1, src_len],[1,src_len]相加时，会自动广播到[batch_size,1,src_len,src_len]\n",
    "        look_ahead_mask = self.generate_square_subsequent_mask(self.max_length)\n",
    "        look_ahead_mask = (\n",
    "            look_ahead_mask.unsqueeze(0).unsqueeze(0).to(encoder_inputs.device)\n",
    "        )  # [1, 1, trg_len, trg_len]\n",
    "\n",
    "        # encoding\n",
    "        encoder_inputs_embeds = self.src_embedding(encoder_inputs)\n",
    "        encoder_outputs = self.encoder(encoder_inputs_embeds) #因为只支持单样本预测，没有paddings，所以不需要mask\n",
    "\n",
    "        # decoding,多样本推理\n",
    "        decoder_inputs = torch.Tensor([self.bos_idx] * encoder_inputs.shape[0]).reshape(-1, 1).long().to(device=encoder_inputs.device)\n",
    "        for cur_len in tqdm(range(1, self.max_length + 1)):\n",
    "            decoder_inputs_embeds = self.trg_embedding(decoder_inputs)\n",
    "            decoder_outputs = self.decoder(\n",
    "                decoder_inputs_embeds=decoder_inputs_embeds,\n",
    "                encoder_outputs=encoder_outputs.last_hidden_states,\n",
    "                attn_mask=look_ahead_mask[:, :, :cur_len, :cur_len],#decoder的自注意力mask\n",
    "            )\n",
    "\n",
    "            logits = self.linear(decoder_outputs.last_hidden_states)\n",
    "            next_token = logits.argmax(dim=-1)[:, -1:] #通过最大下标确定类别，[:, -1:]表示取最后一个结果\n",
    "            decoder_inputs = torch.cat([decoder_inputs, next_token], dim=-1) #预测输出拼接到输入中\n",
    "            #(decoder_inputs == self.eos_idx).sum(dim=-1)是判断样本中是否含有EOS标记\n",
    "            #all是每一个都为True，才会结束\n",
    "            if all((decoder_inputs == self.eos_idx).sum(dim=-1) > 0):\n",
    "                break\n",
    "\n",
    "        return TransformerOutput(\n",
    "            preds=decoder_inputs[:, 1:],\n",
    "            logits=logits,\n",
    "            encoder_last_hidden_states=encoder_outputs.last_hidden_states,\n",
    "            encoder_attn_scores=encoder_outputs.attn_scores,\n",
    "            decoder_last_hidden_states=decoder_outputs.last_hidden_states,\n",
    "            decoder_self_attn_scores=decoder_outputs.self_attn_scores,\n",
    "            decoder_cross_attn_scores=decoder_outputs.cross_attn_scores,\n",
    "        )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "kXHQ3sGTN4yG"
   },
   "source": [
    "## 训练"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "OxNA8DIzN4yG"
   },
   "source": [
    "### 损失函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:27.234057200Z",
     "start_time": "2024-08-05T08:06:27.160089800Z"
    },
    "id": "1xzahHANN4yG"
   },
   "outputs": [],
   "source": [
    "class CrossEntropyWithPadding:\n",
    "    def __init__(self, config):\n",
    "        self.label_smoothing = config[\"label_smoothing\"]\n",
    "\n",
    "    def __call__(self, logits, labels, padding_mask=None):\n",
    "        # logits.shape = [batch size, sequence length, num of classes]\n",
    "        # labels.shape = [batch size, sequence length]\n",
    "        # padding_mask.shape = [batch size, sequence length]\n",
    "        bs, seq_len, nc = logits.shape\n",
    "        loss = F.cross_entropy(logits.reshape(bs * seq_len, nc), labels.reshape(-1), reduce=False, label_smoothing=self.label_smoothing) #label_smoothing表示随机将一个类别的概率设置为0.1，使得模型更加关注其他类别\n",
    "        if padding_mask is None:\n",
    "            loss = loss.mean()\n",
    "        else:\n",
    "            padding_mask = 1 - padding_mask.reshape(-1) #将padding_mask reshape成一维张量，mask部分为0，非mask部分为1\n",
    "            loss = torch.mul(loss, padding_mask).sum() / padding_mask.sum()\n",
    "\n",
    "        return loss\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "zuBC9KqFN4yG"
   },
   "source": [
    "### 学习率衰减"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:27.235056800Z",
     "start_time": "2024-08-05T08:06:27.160089800Z"
    },
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x210b5030380>]"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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RUREpBH6dHcuz763nQslFfh6e/C7hwZwd1gHR8dqMCosIiIijUh5pY3fr9/LX748AsCAzv4kJ0TRpW1zBydrWCosIiIijcTxcyVMWpbB9uMXAPj5zd2YcVcoXh5ujg12A6iwiIiINALrs3J47r3tFJZW4ufjwbyHw7mjX5CjY90wKiwiIiJOrKzSStK6vby95SgAkV1asSghks6tXXsJ6PtUWERERJzUsbPFTFqawc6TBQD84rbuPBvXG093118C+j4VFhERESe0dscpZry/k4tllbRu7sn8R8L5cWigo2M5jAqLiIiIEymtsPLbtbt555tsAAaHtGZhQiQd/Js5OJljqbCIiIg4icNnLjJxaQZ7ThcC8MvbbyLxJ73waIJLQN+nwiIiIuIEVmecZNaqnZSUW2nbwovX4iMY3qudo2M5DRUWERERB7pUbuXXa3axYttxAIZ2b8ProyMJ9PNxcDLnosIiIiLiIAfzipj4Tgb7couwWGDKj3syZURP3N0sjo7mdFRYREREHOC9tBO8uDqLSxVW2vl683p8BMN6BDg6ltNSYREREbmBissqefHDLD5IPwnALT0C+EN8BO18vR2czLmpsIiIiNwge3MKmfhOOofOFONmgcSf9OKp23toCagWVFhEREQamDGGFd8eZ86aXZRV2gj082bh6Eiiu7d1dLRGo04v7F68eDEhISH4+PgQHR3N1q1brzp2165dPPjgg4SEhGCxWFiwYME1H3vu3LlYLBamTZtWl2giIiJO5WJZJVOXZzLjg52UVdoY3qsd66bcqrJiJ7sLy4oVK0hMTGTOnDmkp6cTHh5OXFwceXl5NY4vKSmhe/fuzJ07l6Cga3+q5Lfffsuf/vQnBgwYYG8sERERp7PrVAH3LPqSNdtP4e5m4fk7Q3nrZ4Np21LXq9jL7sLy2muv8fjjjzNhwgT69u3LkiVLaN68OX/9619rHD948GBeffVVRo8ejbf31Q/QxYsXGTt2LH/+859p3bq1vbFERESchjGG//36GPf/cQtH8ovp6O/Du78YylO334SbrlepE7sKS3l5OWlpacTGxv7rAdzciI2NJTU19QcFmThxIiNHjqz22NdSVlZGYWFhtZuIiIijFZZWMGlpBi+uzqK80kZsn/Z8NOVWBnZt4+hojZpdF93m5+djtVoJDKz+aZGBgYHs3bu3ziGWL19O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QIDJy8szxlx+6VqXLl3MZ599ZrZt22ZiYmJMTExM1f7fvXTtjjvuMJmZmWb9+vWmXbt2Nb50bfr06WbPnj1m8eLFDfay5qKiIpORkWEyMjIMYF577TWTkZFhjh07Zoy5/LLmVq1amQ8//NDs2LHD3HfffTW+rDkyMtJ888035ssvvzQ9e/as9pLfCxcumMDAQPPoo4+arKwss3z5ctO8efMrXvLr4eFh5s2bZ/bs2WPmzJlTby9rvtYci4qKzLPPPmtSU1PNkSNHzKeffmqioqJMz549TWlpaaOY41NPPWX8/f3Nxo0bq70stKSkpGrMjfq5bIjf4+vN7+DBg+Y3v/mN2bZtmzly5Ij58MMPTffu3c1tt93WKOZnjDEzZswwmzZtMkeOHDE7duwwM2bMMBaLxfzzn/80xjTu43e9+bnC8avJ91/51NiOoQrLdSxatMh06dLFeHl5mSFDhpivv/7a0ZGuEB8fbzp06GC8vLxMp06dTHx8vDl48GDV/ZcuXTK//OUvTevWrU3z5s3N/fffb06fPl3tMY4ePWruuusu06xZMxMQEGCeeeYZU1FRUW3M559/biIiIoyXl5fp3r27eeuttxpkPp9//rkBrriNHz/eGHP5pc0vvviiCQwMNN7e3mbEiBFm37591R7j7NmzJiEhwbRs2dL4+fmZCRMmmKKiompjtm/fbm655Rbj7e1tOnXqZObOnXtFlnfffdf06tXLeHl5mX79+pmPPvqowedYUlJi7rjjDtOuXTvj6elpunbtah5//PErfrmdeY41zQ2o9jNzI38u6/v3+Hrzy87ONrfddptp06aN8fb2Nj169DDTp0+v9j4ezjw/Y4z5+c9/brp27Wq8vLxMu3btzIgRI6rKijGN+/hdb36ucPxq8v3C0tiOocUYY+x7TkZERETkxtI1LCIiIuL0VFhERETE6amwiIiIiNNTYRERERGnp8IiIiIiTk+FRURERJyeCouIiIg4PRUWERERcXoqLCIiIuL0VFhERETE6amwiIiIiNNTYRERERGn939a+EZEJEJHuwAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "x=np.arange(1, 40000)\n",
    "plt.plot(x, x * (4000 ** (-1.5)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:27.235056800Z",
     "start_time": "2024-08-05T08:06:27.161089200Z"
    },
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "22.627416997969522"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sqrt(512)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:27.235056800Z",
     "start_time": "2024-08-05T08:06:27.161089200Z"
    },
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 449
    },
    "id": "UQPiKK4nN4yG",
    "outputId": "63cfb132-ef75-4f94-f0c8-86a2f36e09c2"
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlEAAAGwCAYAAACJjDBkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAABqiklEQVR4nO3de1xUdf4/8NcMw8xwmxkQYUARMFG8oKYoYaaVs2G5bXRZzbU0c9VtdVfXyrL1Um2/pbXLmq3l13XL2jU1t7IyZSO8poiK9xveEPACCCPD/Tbz+f2BnJxEBZzhMMPr+XjMAzjnfc68PzPgvP18PudzFEIIASIiIiJqFqXcCRARERG5IhZRRERERC3AIoqIiIioBVhEEREREbUAiygiIiKiFmARRURERNQCLKKIiIiIWkAldwLuzGaz4eLFi/Dz84NCoZA7HSIiImoCIQRKS0sRGhoKpfLG/U0sopzo4sWLCAsLkzsNIiIiaoHc3Fx07tz5hvtZRDmRn58fgPo3QafTyZwNERERNUVJSQnCwsKkz/EbYRHlRA1DeDqdjkUUERGRi7nVVBxOLCciIiJqARZRRERERC3AIoqIiIioBVhEEREREbUAiygiIiKiFmARRURERNQCLKKIiIiIWoBFFBEREVELsIgiIiIiagEWUUREREQt0CaKqCVLliAiIgJarRZxcXHYvXv3TePXrl2L6OhoaLVaxMTEYMOGDXb7hRCYP38+QkJC4OXlBZPJhFOnTtnFmM1mjBs3DjqdDgaDAZMmTUJZWZm0/9VXX4VCobju4ePj47iGExERkcuSvYhas2YNZs2ahQULFmDfvn3o168fEhISUFBQ0Gj8zp07MXbsWEyaNAn79+9HYmIiEhMTceTIESlm4cKFWLx4MZYuXYr09HT4+PggISEBVVVVUsy4ceNw9OhRpKSkYP369di2bRumTJki7X/hhRdw6dIlu0evXr3w61//2nkvBhEREbkOIbPBgweLadOmST9brVYRGhoqkpKSGo0fPXq0GDVqlN22uLg4MXXqVCGEEDabTRiNRvHWW29J+4uLi4VGoxGrVq0SQghx7NgxAUDs2bNHitm4caNQKBTiwoULjT7vgQMHBACxbdu2G7alqqpKWCwW6ZGbmysACIvFcotXwf3ZbDZRW2eVOw0iIqJbslgsTfr8lrUnqqamBhkZGTCZTNI2pVIJk8mEtLS0Ro9JS0uziweAhIQEKT4rKwt5eXl2MXq9HnFxcVJMWloaDAYDYmNjpRiTyQSlUon09PRGn3f58uXo3r077rnnnhu2JykpCXq9XnqEhYXd4hVoP577zz7clbQJl0ur5U6FiIjIIWQtogoLC2G1WhEcHGy3PTg4GHl5eY0ek5eXd9P4hq+3igkKCrLbr1KpEBAQ0OjzVlVVYeXKlZg0adJN2zNnzhxYLBbpkZube9P49sJmE0g+mofCsmp8mnZO7nSIiIgcQiV3Aq7gq6++QmlpKSZMmHDTOI1GA41G00pZuY68kp/moh2/VCpjJkRERI4ja09UYGAgPDw8kJ+fb7c9Pz8fRqOx0WOMRuNN4xu+3irm5xPX6+rqYDabG33e5cuX45e//OV1vVvUNDnmCun79LNFqLXaZMyGiIjIMWQtotRqNQYOHIjU1FRpm81mQ2pqKuLj4xs9Jj4+3i4eAFJSUqT4yMhIGI1Gu5iSkhKkp6dLMfHx8SguLkZGRoYUs2nTJthsNsTFxdmdOysrC5s3b77lUB7d2LVFVGl1HQ7kFsuXDBERkYPIPpw3a9YsTJgwAbGxsRg8eDAWLVqE8vJyTJw4EQAwfvx4dOrUCUlJSQCAGTNmYPjw4XjnnXcwatQorF69Gnv37sWyZcsAAAqFAjNnzsQbb7yBqKgoREZGYt68eQgNDUViYiIAoGfPnhg5ciQmT56MpUuXora2FtOnT8eTTz6J0NBQu/w++ugjhISE4MEHH2y9F8XN5BRV2P28NfMyBkUEyJQNERGRY8heRI0ZMwaXL1/G/PnzkZeXh/79+yM5OVkaOsvJyYFS+VOH2ZAhQ/DZZ59h7ty5eOWVVxAVFYV169ahT58+Uszs2bNRXl6OKVOmoLi4GEOHDkVycjK0Wq0Us3LlSkyfPh0jRoyAUqnE448/jsWLF9vlZrPZsGLFCjzzzDPw8PBw8ivhvhp6oqKNfjiRV4qtJy/jhYQeMmdFRER0exRCCCF3Eu6qpKQEer0eFosFOp1O7nRkk7hkBw7kFuMviX0wb139oqh755oQ6MtJ+ERE1PY09fNb9hXLyf019EQN6GJA79D6X8btpy7LmRIREdFtYxFFTlVaVQtzeQ0AICzAG8O7dwRQPy+KiIjIlbGIIqfKNVcCAPy9PaHTekpF1LZThbDaOJJMRESui0UUOVWOuRwA0KWDDwBgQLg/dFoVzOU1OJB7Rc7UiIiIbguLKHKqhvlQXQK8AQCeHkrcF11/y53vj+Xf8DgiIqK2jkUUOVVDERV+tYgCAFPP+uUrfmARRURELoxFFDlVdpF9TxQADO/REZ4eCpy5XI6zl8vkSo2IiOi2sIgip8q92hMVdk0RpdN64q6uHQAAPxxnbxQREbkmFlHkNFabwPkr9VfnhXfwttv305BewXXHERERuQIWUeQ0F4srUWcTUHsoEazT2u0z9aovovZmm6V1pIiIiFwJiyhymoahvM7+XvBQKuz2dTJ4oVeIDjYBbDrB3igiInI9LKLIaaTlDX42lNegoTfq+6N5rZYTERGRo7CIIqfJNl9/Zd61HrhaRG09eRnl1XWtlhcREZEjsIgip/n5Qps/1ztUh4gO3qiusyGVQ3pERORiWESR0+Q0skbUtRQKBR6KCQEAbDh0qdXyIiIicgQWUeQ0t5oTBUAqojZnFnBIj4iIXAqLKHIKS0UtLJW1AIAw/xsXUb1DdQi/OqTHq/SIiMiVsIgip2johQr01cBHo7ph3LVDet9xSI+IiFwIiyhyip8mlXvdMnYUh/SIiMgFsYgip7jVlXnX4pAeERG5IhZR5BQ55nIAQJcOPreMvXZI79uDF52aFxERkaOwiCKnaE5PFAA80j8UQP2QXnEF76VHRERtH4socormFlHRRh16huhQaxVYzwnmRETkAlhEkcPVWm24WFwFAAi/yRpRP/fonfW9Uev2X3BKXkRERI7EIooc7mJxJaw2AY1KiY6+miYf90j/TlAqgL3ZV6TVzomIiNoqFlHkcA1DeWEB3lAqFU0+Llinxd3dAgEA6w6wN4qIiNo2FlHkcNlXe5HCmzgf6lqJ/TsBAL7afwFCCIfmRURE5Egsosjhcq/piWqukX2M8PL0QFZhOQ6etzg6NSIiIodhEUUO19wr867lo1Hhgd7BAIAvMs47NC8iIiJHYhFFDicN5zXjyrxrPTGwM4D6eVFVtVaH5UVERORILKLIoYQQ0nBeS3qiAODuOwLR2d8LpVV12HiEa0YREVHbxCKKHKq4ohalV28i3JI5UQCgVCowJjYMALB6d67DciMiInIkFlHkUNlXe6GCdRpoPT1afJ4nYjtDqQDSs8w4e7nMUekRERE5DIsocqjbmVR+rRC9F+7tEQQAWLOXvVFERNT2sIgih/ppPpTPbZ9rzKD6Ib0vMs6j1mq77fMRERE5EosocqjsonIAt98TBQD3Rwch0FeDwrIapB4vuO3zERERORKLKHIoaTivg9dtn8vTQyktd7AyPfu2z0dERORIshdRS5YsQUREBLRaLeLi4rB79+6bxq9duxbR0dHQarWIiYnBhg0b7PYLITB//nyEhITAy8sLJpMJp06dsosxm80YN24cdDodDAYDJk2ahLKysuvO8/bbb6N79+7QaDTo1KkT/t//+3+OabQbyzVXAnDMcB4A/GZwFygUwPZThZxgTkREbYqsRdSaNWswa9YsLFiwAPv27UO/fv2QkJCAgoLGh2527tyJsWPHYtKkSdi/fz8SExORmJiII0eOSDELFy7E4sWLsXTpUqSnp8PHxwcJCQmoqqqSYsaNG4ejR48iJSUF69evx7Zt2zBlyhS755oxYwaWL1+Ot99+GydOnMA333yDwYMHO+eFcBPVdVZctDQUUbc/nAcAXTp44/6rE8w/TWNvFBERtSFCRoMHDxbTpk2TfrZarSI0NFQkJSU1Gj969GgxatQou21xcXFi6tSpQgghbDabMBqN4q233pL2FxcXC41GI1atWiWEEOLYsWMCgNizZ48Us3HjRqFQKMSFCxekGJVKJU6cONGs9lRVVQmLxSI9cnNzBQBhsViadR5XdaagVIS/tF70nLdR2Gw2h513a2aBCH9pvegzP1mUVtU67LxERESNsVgsTfr8lq0nqqamBhkZGTCZTNI2pVIJk8mEtLS0Ro9JS0uziweAhIQEKT4rKwt5eXl2MXq9HnFxcVJMWloaDAYDYmNjpRiTyQSlUon09HQAwLfffouuXbti/fr1iIyMREREBH7729/CbDbftE1JSUnQ6/XSIywsrBmviOvLvmZ5A4VC4bDzDu0WiK6BPiitrsNX+y847LxERES3Q7YiqrCwEFarFcHBwXbbg4ODkZeX1+gxeXl5N41v+HqrmKCgILv9KpUKAQEBUszZs2eRnZ2NtWvX4tNPP8WKFSuQkZGBJ5544qZtmjNnDiwWi/TIzW1f6xs1LG/Q0pXKb0SpVGB8fDgA4NOd5yCEcOj5iYiIWkIldwJtkc1mQ3V1NT799FN0794dAPCvf/0LAwcORGZmJnr06NHocRqNBhqNpjVTbVNyihyz0GZjHh/YGW/9LxOnCsqQdqYIQ7oFOvw5iIiImkO2nqjAwEB4eHggPz/fbnt+fj6MRmOjxxiNxpvGN3y9VczPJ67X1dXBbDZLMSEhIVCpVFIBBQA9e/YEAOTk5DSrne1Jw3BeeAfHF1F+Wk88NqB+uYOPd55z+PmJiIiaS7YiSq1WY+DAgUhNTZW22Ww2pKamIj4+vtFj4uPj7eIBICUlRYqPjIyE0Wi0iykpKUF6eroUEx8fj+LiYmRkZEgxmzZtgs1mQ1xcHADg7rvvRl1dHc6cOSPFnDx5EgAQHh5+O812a84azmswYUgEAOCH4/lc7oCIiGQn6xIHs2bNwj//+U988sknOH78OJ577jmUl5dj4sSJAIDx48djzpw5UvyMGTOQnJyMd955BydOnMCrr76KvXv3Yvr06QAAhUKBmTNn4o033sA333yDw4cPY/z48QgNDUViYiKA+h6lkSNHYvLkydi9ezd27NiB6dOn48knn0RoaCiA+onmAwYMwLPPPov9+/cjIyMDU6dOxS9+8Qu73in6iRDCYffNu5FuQb4YER0EIYDlP2Y55TmIiIiaStYiasyYMXj77bcxf/589O/fHwcOHEBycrI0MTwnJweXLl2S4ocMGYLPPvsMy5YtQ79+/fDf//4X69atQ58+faSY2bNn4w9/+AOmTJmCQYMGoaysDMnJydBqtVLMypUrER0djREjRuChhx7C0KFDsWzZMmm/UqnEt99+i8DAQAwbNgyjRo1Cz549sXr16lZ4VVxTYVkNKmqsUCiAzv63v1r5jUwZ1hUA8N+M8ygsq3ba8xAREd2KQvBSJ6cpKSmBXq+HxWKBTqeTOx2nysi+gsc/3IlQvRY754xw2vMIIZD4wU4czC3GH+/vhlkPND7Jn4iIqKWa+vkt+21fyD04ez5UA4VCgalXe6M+3ZWNipo6pz4fERHRjbCIIofILnLelXk/l9DbiPAO3iiuqMXaveed/nxERESNYRFFDuHsSeXX8lAq8NuhkQCA5T+eRZ3V5vTnJCIi+jkWUeQQrTWc1+CJgWEI8FEj11yJrw9cbJXnJCIiuhaLKHKIbHM5ACC8g0+rPJ+X2gOT76mfG/WPzadhtfH6CCIial0soui2VdVakV9Sv9xAawznNXg6PhwGb09kFZZj/SH2RhERUetiEUW37fyV+qE8P40K/t6erfa8vhqVNDfq/U3sjSIiotbFIopuW8OVeWEB3lAoFK363OOHRECnVeF0QRk2Hrl06wOIiIgchEUU3bbWvDLv53RaT0waWj836v3U07CxN4qIiFoJiyi6bQ1FVGusEdWYZ+6OgJ9Ghcz8Umw8kidLDkRE1P6wiKLbllPUussb/JzeyxPPXp0b9U5KJteNIiKiVsEiim6bnMN5DX57TyT8vT1x9nI5vtjHVcyJiMj5WETRbRFCyD6cBwB+Wk9Mu68bAGDRD6dQVWuVLRciImofWETRbSkorUZ1nQ1KBRBq8JI1l6fuCkeoXotLlir8Z1e2rLkQEZH7YxFFt6WhFyrU4AVPD3l/nbSeHphp6g4AWLL5NEqqamXNh4iI3BuLKLotDWtEyTmUd63HBnTCHR19cKWiFsu3nZU7HSIicmMsoui2tIVJ5ddSeSjxYkIPAMA/t2chz1Ilc0ZEROSuWETRbck1y7u8QWMSehsRG+6PylorFv7vhNzpEBGRm2IRRbclu6gcABAe4CNzJj9RKBSY/3AvAMCX+y7gYG6xvAkREZFbYhFFtyXHXAmg7QznNejb2YDHB3QGALy+/hiE4O1giIjIsVhEUYtV1NShsKwaQNsrogBg9sge8PL0QEb2Faw/xJsTExGRY7GIohZrmFSu9/KE3ttT5myuF6zT4vf33gEAeHPjCS7ASUREDsUiilqs4Z55bbEXqsHkYV0RqtfiQnElPtxyRu50iIjIjbCIohZra8sbNEbr6YE/j6qfZP7h1jM4V1guc0ZEROQuWERRi0lFVBtZaPNGHoox4p6oQNTU2TDv6yOcZE5ERA7BIopazBV6ooD6JQ/+8kgfqFVKbD9ViO8Oc5I5ERHdPhZR1GKuUkQBQESgD54bXj/J/PVvj6GU99UjIqLbxCKKWsRqEzjfRteIupHn7r0DER28UVBajb+nnJI7HSIicnEsoqhF8kuqUGO1QaVUIESvlTudJtF6euD1R/oAAFbszMKh88XyJkRERC6NRRS1SMNQXid/L6g8XOfXaFj3jvhVv1DYBDD7v4dQU2eTOyUiInJRrvPpR22KK6wRdSMLHu6FDj5qnMgrxQdbTsudDhERuSgWUdQirjSp/Oc6+Grw2iO9AQD/2HQaxy+VyJwRERG5IhZR1CINRVR4G18j6kZGxYQgoXcw6mwCs/97CHVWDusREVHzsIiiFsl24Z4o4Ke1o/Renjh8wYJl28/KnRIREbkYFlHUIrlXi6gwFy2iACBIp8X8X9bfEmZRyikO6xERUbOwiKJmK62qhbm8BoDr9kQ1eGxAJ5h6BqPGasPM1QdQVWuVOyUiInIRLKKo2RrmQwX4qOGn9ZQ5m9ujUCjwt8djEOirQWZ+KRYmZ8qdEhERuYg2UUQtWbIEERER0Gq1iIuLw+7du28av3btWkRHR0Or1SImJgYbNmyw2y+EwPz58xESEgIvLy+YTCacOmW/QrXZbMa4ceOg0+lgMBgwadIklJWVSfvPnTsHhUJx3WPXrl2Oa7iLcoehvGt18NXgrSf6AgA+2pGFbScvy5wRERG5AtmLqDVr1mDWrFlYsGAB9u3bh379+iEhIQEFBQWNxu/cuRNjx47FpEmTsH//fiQmJiIxMRFHjhyRYhYuXIjFixdj6dKlSE9Ph4+PDxISElBVVSXFjBs3DkePHkVKSgrWr1+Pbdu2YcqUKdc93w8//IBLly5Jj4EDBzr+RXAx0pV5blJEAcB90UEYHx8OAHhh7UFcuTpcSUREdENCZoMHDxbTpk2TfrZarSI0NFQkJSU1Gj969GgxatQou21xcXFi6tSpQgghbDabMBqN4q233pL2FxcXC41GI1atWiWEEOLYsWMCgNizZ48Us3HjRqFQKMSFCxeEEEJkZWUJAGL//v0tbpvFYhEAhMViafE52qJXvjwkwl9aL95KPiF3Kg5VUV0n7n97swh/ab2Y8ukeYbPZ5E6JiIhk0NTPb1l7ompqapCRkQGTySRtUyqVMJlMSEtLa/SYtLQ0u3gASEhIkOKzsrKQl5dnF6PX6xEXFyfFpKWlwWAwIDY2VooxmUxQKpVIT0+3O/evfvUrBAUFYejQofjmm29u2p7q6mqUlJTYPdyRKy+0eTNeag+89+Sd8PRQ4H9H8/HJznNyp0RERG2YrEVUYWEhrFYrgoOD7bYHBwcjLy+v0WPy8vJuGt/w9VYxQUFBdvtVKhUCAgKkGF9fX7zzzjtYu3YtvvvuOwwdOhSJiYk3LaSSkpKg1+ulR1hY2K1eApckFVEuutDmzfTppMecB3sCAP7fhuM4mFssb0JERNRmyT4nqq0KDAzErFmzEBcXh0GDBuHNN9/EU089hbfeeuuGx8yZMwcWi0V65ObmtmLGraPOasOFK5UA3K8nqsHEuyMwsrcRtVaB36/cB0tFrdwpERFRGyRrERUYGAgPDw/k5+fbbc/Pz4fRaGz0GKPReNP4hq+3ivn5xPW6ujqYzeYbPi8AxMXF4fTpG9+wVqPRQKfT2T3czSVLFepsAmoPJYJ1WrnTcQqFQoG/PdEXXQK8caG4Ei/89yCEEHKnRUREbYysRZRarcbAgQORmpoqbbPZbEhNTUV8fHyjx8THx9vFA0BKSooUHxkZCaPRaBdTUlKC9PR0KSY+Ph7FxcXIyMiQYjZt2gSbzYa4uLgb5nvgwAGEhIQ0v6FupGEor3OAFzyUCpmzcR69lyc+GDcAag8lUo7lY/n2LLlTIiKiNkYldwKzZs3ChAkTEBsbi8GDB2PRokUoLy/HxIkTAQDjx49Hp06dkJSUBACYMWMGhg8fjnfeeQejRo3C6tWrsXfvXixbtgxAfS/CzJkz8cYbbyAqKgqRkZGYN28eQkNDkZiYCADo2bMnRo4cicmTJ2Pp0qWora3F9OnT8eSTTyI0NBQA8Mknn0CtVuPOO+8EAHz55Zf46KOPsHz58lZ+hdoWd51U3pg+nfSY98uemPf1UbyZfAJ9OukRf0cHudMiIqI2QvYiasyYMbh8+TLmz5+PvLw89O/fH8nJydLE8JycHCiVP3WYDRkyBJ999hnmzp2LV155BVFRUVi3bh369OkjxcyePRvl5eWYMmUKiouLMXToUCQnJ0Or/Wn4aeXKlZg+fTpGjBgBpVKJxx9/HIsXL7bL7S9/+Quys7OhUqkQHR2NNWvW4IknnnDyK9K2taciCgCeuisce7Ov4OsDFzHts334Zvrd6OzfPtpOREQ3pxCc7OE0JSUl0Ov1sFgsbjM/atrKffju8CXMHdUTv72nq9zptIrKGiueWLoTRy+WoFeIDl88NwReag+50yIiIidp6uc3r86jZmlvPVFA/fpRy8bHooOPGsculWD2F4c40ZyIiFhEUfO48xpRN9PJ4IUPxg2ASqnAtwcvYtm2s3KnREREMmMRRU1mqaiFpbJ+zaT21BPVIK5rByx4uBcA4G/JJ5B6PP8WRxARkTtjEUVN1tALFeirgbda9msSZPHUXeEYO7gLbAKY/tl+HLlgkTslIiKSCYsoarKf5kN5yZyJfBQKBV5/pDfuiQpEZa0Vz67YgwvFlXKnRUREMmARRU2WbS4HAIR38JE5E3l5eiixZNwA9Aj2Q0FpNZ79eA9KqnhrGCKi9oZFFDVZ7tWeqLB2OB/q53RaT3w0cRA6+mmQmV+KaSv3odZqkzstIiJqRSyiqMkahvPCWUQBqL9i76MJg+Dl6YHtpwox58vDXPqAiKgdYRFFTZZd1D6XN7iZmM56/OM3d0KpAP6bcR5/3XCchRQRUTvBIoqapNZqw8WrE6jb4/IGNzOiZzDefLwvAOCf27Pw4dYzMmdEREStgUUUNcnF4krYBKBRKRHkp5E7nTZndGwY/vxQTwDAwuRMfJaeI3NGRETkbCyiqEmkobwAbygUCpmzaZsmD+uK3997BwDgz+sOY8PhSzJnREREzsQiipqkPd4zryVeTOiBsYO7QAhgxur92HSCq5oTEbkrFlHUJLnt9J55zaVQKPBGYh+M6huCWqvA7/69D1syC+ROi4iInIBFFDXJtcN5dHMeSgUWjemPkb2NqLHaMOXfGdh+6rLcaRERkYOxiKIm4XBe83h6KLF47J34Ra9g1NTZ8NtP9mLH6UK50yIiIgdiEUW3JIT4aaFNDuc1mVqlxJLfDICpZxCq62yY9Mke7DzDQoqIyF2wiKJbulJRi7LqOgBAZ38WUc2hVtXfZ+/+6CBU1drw7Io92HqSQ3tERO6ARRTdUkMvVLBOA62nh8zZuB6NygMfXFNI/faTPUg+wuUPiIhcHYsouqXsonIAQHiAj8yZuC6tpweWPjUQo2Lqr9qb9tl+fLX/vNxpERHRbWhREXXmzBnMnTsXY8eORUFB/eXbGzduxNGjRx2aHLUNDcsbhHFS+W1Rq+onm/96YGdYbQKzPj+I/+zKljstIiJqoWYXUVu3bkVMTAzS09Px5ZdfoqysDABw8OBBLFiwwOEJkvx4ZZ7jeCgV+NvjffHMkAgIAcxddwQfbjnDmxYTEbmgZhdRL7/8Mt544w2kpKRArVZL2++//37s2rXLoclR29CwRhSvzHMMpVKBBQ/3km4R87fkE3jt22Ow2lhIERG5kmYXUYcPH8ajjz563fagoCAUFvLybXfE4TzHUygUmD0yGnNH1d+0eMXOc5j+2T5U1VplzoyIiJqq2UWUwWDApUvXX1m0f/9+dOrUySFJUdtRXWfFpZIqABzOc4bf3tMVi8feCbWHEhuP5GH8v3ajuKJG7rSIiKgJml1EPfnkk3jppZeQl5cHhUIBm82GHTt24IUXXsD48eOdkSPJ6PyVSggBeKs9EOirvvUB1Gy/6heKT54dDD+tCrvPmfHE0jRcKK6UOy0iIrqFZhdRf/3rXxEdHY2wsDCUlZWhV69eGDZsGIYMGYK5c+c6I0eS0bWTyhUKhczZuK/4Ozpg7e/iYdRpcbqgDIlLdmB/zhW50yIioptodhGlVqvxz3/+E2fPnsX69evxn//8BydOnMC///1veHhwIUZ3w/lQrSfaqMOXvx+CaKMfLpdWY8yyXfj6wAW50yIiohtodhH1+uuvo6KiAmFhYXjooYcwevRoREVFobKyEq+//rozciQZSVfmsYhqFaEGL/z3uSEw9QxCTZ0NM1YfwDvfZ8LGK/eIiNqcZhdRr732mrQ21LUqKirw2muvOSQpajuk4Twub9BqfDUq/N/TsZg6vCsA4P1NpzHts32oqKmTOTMiIrpWs4soIUSjc2MOHjyIgIAAhyRFbQeH8+ThoVRgzoM98fav+0lX7v16aZr0fhARkfxUTQ309/eHQqGAQqFA9+7d7Qopq9WKsrIy/O53v3NKkiQPIYTUE8XhPHk8MbAzIjp4Y+q/M3D0Ygke/sePeO/JOzG8e0e5UyMiaveaXEQtWrQIQgg8++yzeO2116DX66V9arUaERERiI+Pd0qSJI/CshpU1FihUACd/L3kTqfdio0IwDd/GIrn/pOBQ+cteObj3fiTqTum39cNSiWvmCQikkuTi6gJEyYAACIjIzFkyBB4eno6LSlqGxp6oUL1XtCoeOWlnDoZvPD51Hi89u0xrNqdg3dTTuJAbjH+Pro/9N78WyQikkOz50QNHz5cKqCqqqpQUlJi9yD3kWMuBwCEBbAXqi3Qenog6bEYLHyiL9QqJTadKMDD//gRRy9a5E6NiKhdanYRVVFRgenTpyMoKAg+Pj7w9/e3e5D7yCmqXzWbt3tpW0bHhuHL54ags78XcswVeHTJTnyy8xyE4DIIREStqdlF1IsvvohNmzbhww8/hEajwfLly/Haa68hNDQUn376qTNyJJlIk8o7+MicCf1cn056rP/DUIyIDkKN1YYF3xzFlH9n4Eo577tHRNRaml1Effvtt/jggw/w+OOPQ6VS4Z577sHcuXPx17/+FStXrmxREkuWLEFERAS0Wi3i4uKwe/fum8avXbsW0dHR0Gq1iImJwYYNG+z2CyEwf/58hISEwMvLCyaTCadOnbKLMZvNGDduHHQ6HQwGAyZNmtTo+lcAcPr0afj5+cFgMLSofa7qp+E89kS1RQZvNZZPiMWCh3tB7aFEyrF8PLR4O9LPFsmdGhFRu9DsIspsNqNr1/pFAHU6HcxmMwBg6NCh2LZtW7MTWLNmDWbNmoUFCxZg37596NevHxISElBQUNBo/M6dOzF27FhMmjQJ+/fvR2JiIhITE3HkyBEpZuHChVi8eDGWLl2K9PR0+Pj4ICEhAVVVVVLMuHHjcPToUaSkpGD9+vXYtm0bpkyZct3z1dbWYuzYsbjnnnua3TZXd+1986htUigUmHh3JL78/RBEBvrgkqUKY/+5C39POQkrVzknInIu0UwxMTFiy5YtQgghRowYIZ5//nkhhBDvvfee6NSpU3NPJwYPHiymTZsm/Wy1WkVoaKhISkpqNH706NFi1KhRdtvi4uLE1KlThRBC2Gw2YTQaxVtvvSXtLy4uFhqNRqxatUoIIcSxY8cEALFnzx4pZuPGjUKhUIgLFy7YnXv27NniqaeeEh9//LHQ6/XNapvFYhEAhMViadZxbUFlTZ0If2m9CH9pvTCXVcudDjVBWVWtmLXmgPS+PfbBDpF1uUzutIiIXE5TP7+b3RM1ceJEHDx4EADw8ssvY8mSJdBqtfjTn/6EF198sVnnqqmpQUZGBkwmk7RNqVTCZDIhLS2t0WPS0tLs4gEgISFBis/KykJeXp5djF6vR1xcnBSTlpYGg8GA2NhYKcZkMkGpVCI9PV3atmnTJqxduxZLlixpUnuqq6vd5mrFhpWx/TQqGHgJvUvw0ajwzuh+WDSmP/w0KmRkX8GD723Hv9M46ZyIyBmavE5Ugz/96U/S9yaTCSdOnEBGRga6deuGvn37NutchYWFsFqtCA4OttseHByMEydONHpMXl5eo/F5eXnS/oZtN4sJCgqy269SqRAQECDFFBUV4ZlnnsF//vMf6HS6JrUnKSnJbe4fmHPN7V4au80PtV2Jd3bCoMgAvLj2IHaeKcK8r4/i+2P5WPhEX4TouVwFEZGjNKsnqra2FiNGjLCbpB0eHo7HHnus2QVUWzd58mT85je/wbBhw5p8zJw5c2CxWKRHbm6uEzN0ruyihivzOB/KFXUyeOE/k+Kw4OFe0KiU2H6qEAl/34Z1+y+wV4qIyEGaVUR5enri0KFDDnvywMBAeHh4ID8/3257fn4+jEZjo8cYjcabxjd8vVXMzyeu19XVwWw2SzGbNm3C22+/DZVKBZVKhUmTJsFisUClUuGjjz5qNDeNRgOdTmf3cFWcVO76lMr6Seff/fEe9OusR0lVHWauOYAp/85AnqXq1icgIqKbavacqKeeegr/+te/HPLkarUaAwcORGpqqrTNZrMhNTX1hvfhi4+Pt4sHgJSUFCk+MjISRqPRLqakpATp6elSTHx8PIqLi5GRkSHFbNq0CTabDXFxcQDq500dOHBAerz++uvw8/PDgQMH8Oijjzqk/W1Z7jXDeeTaugX54ovnhmDWL7rD00OBlGP5+MW7W7EyPRs2XsFHRNRizZ4TVVdXh48++gg//PADBg4cCB8f+4UY33333Wadb9asWZgwYQJiY2MxePBgLFq0COXl5Zg4cSIAYPz48ejUqROSkpIAADNmzMDw4cPxzjvvYNSoUVi9ejX27t2LZcuWAai/5HvmzJl44403EBUVhcjISMybNw+hoaFITEwEAPTs2RMjR47E5MmTsXTpUtTW1mL69Ol48sknERoaKsVca+/evVAqlejTp09zXzKXlG3mcJ47UXko8ccRUUjobcRLXxzCgdxi/PmrI/j6wEUkPRaDOzr6yp0iEZHLaXYRdeTIEQwYMAAAcPLkSbt9LZmAPGbMGFy+fBnz589HXl4e+vfvj+TkZGlieE5ODpTKnzrMhgwZgs8++wxz587FK6+8gqioKKxbt86uuJk9ezbKy8sxZcoUFBcXY+jQoUhOToZWq5ViVq5cienTp2PEiBFQKpV4/PHHsXjx4mbn745sNiH1RHE4z730MPrhi+eG4JOd5/DW/zKxO8uMB9/bjhkjojBlWFd4ejS7c5qIqN1SCM4ydZqSkhLo9XpYLBaXmh+VX1KFuL+mwkOpwIm/jOQHq5vKNVfgz+uOYNvJywCAHsF+eP2R3ojr2kHmzIiI5NXUz29+OtJ1Gq7MCzVoWUC5sbAAb3wycRD+PqYf/L09kZlfijHLduFPaw6goJQTz4mIboWfkHQdXpnXfigUCjx6Z2dsev5ejB3cBQoF8NX+Cxjx9lZ8vCMLdVab3CkSEbVZLKLoOiyi2h9/HzWSHovBV7+/G30761FaXYfXvj2GX77/I/aeM8udHhFRm8Qiiq6TU1QOAOgS4HOLSHI3/cMM+Or3d+P/PdoHei9PnMgrxRNL0/DHVftx/kqF3OkREbUpLKLoOuyJat88lAqMiwvH5hfuxZjYMCgUwDcHL2LEO1vx1v9OoKy6Tu4UiYjahGYvcfDNN980ul2hUECr1aJbt26IjIy87cRIPjnmSgAsotq7AB81/vZEXzwdH46/rD+G9Cwzlmw+gzV7zuOFB7rj17Fh8FDyvopE1H41e4kDpVIJhUJx3f23GrYpFAoMHToU69atg7+/v0OTdTWuuMRBeXUdei/4HwDg4IIHoPfylDkjaguEEPj+WD6SNhzHuatXb0Yb/TB3VC8MjQqUOTsiIsdy2hIHKSkpGDRoEFJSUqQb7aakpCAuLg7r16/Htm3bUFRUhBdeeOG2GkDyyL0670Xv5ckCiiQKhQIJvY34/k/DMXdUT+i0KpzIK8VT/0rH0/9Kx+HzFrlTJCJqdc0ezpsxYwaWLVuGIUOGSNtGjBgBrVaLKVOm4OjRo1i0aBGeffZZhyZKrSOniLd7oRtTq5T47T1d8fiAzngv9RT+sysb208VYvupH/FQjBHPP9CDt5Ahonaj2T1RZ86cabRrS6fT4ezZswCAqKgoFBYW3n521OpyeONhagJ/HzVe/VVvbHr+Xjx6ZycoFMCGw3l44O/b8PIXh3DJUil3ikRETtfsImrgwIF48cUXcfnyZWnb5cuXMXv2bAwaNAgAcOrUKYSFhTkuS2o1vDKPmqNLB2/8fUx/bJxxD0w9g2C1Cazek4vhb23BG+uPoaisWu4UiYicptlF1L/+9S9kZWWhc+fO6NatG7p164bOnTvj3LlzWL58OQCgrKwMc+fOdXiy5HwNRVQ4iyhqhmijDssnDMIXz8UjLjIANXU2LP8xC0P/thl/3XAcl0tZTBGR+2nRDYhtNhu+//57nDx5EgDQo0cP/OIXv4BSyWWnruWKV+fd//YWnC0sx2e/jcOQbrzqippPCIFtpwrxzveZOHR1wrnWU4lxceGYOrwrgvy0MmdIRHRzTf38blERRU3jakWU1SbQc14yaqw2bJ99H+dF0W0RQmDLyct474dTOJBbDADQqJQYO7gLnrv3DgTrWEwRUdvU1M/vZl+dBwCpqalITU1FQUEBbDb7G5R+9NFHLTkltQH5JVWosdqgUioQavCSOx1ycQqFAvf1CMK93Tti26lCvPfDSezLKcaKnefw2e4cjIkNw5RhXVmsE5HLanYR9dprr+H1119HbGwsQkJCoFBwxWJ3kX11eYPO/l5ciZocRqFQYHj3jhgWFYgdp4vwXupJ7Dl3Bf/elY3PdudgVEwIpg7vit6herlTJSJqlmYXUUuXLsWKFSvw9NNPOyMfklEulzcgJ1IoFBgaFYi7u3VA2tkifLjlDLafKsQ3By/im4MXMax7R/xuWFfE39GB/zkjIpfQ7CKqpqbGbqFNch/Z5nIAXGiTnEuhUGDIHYEYckcgjlyw4P+2ncV3hy5i28nL2HbyMvp11mPq8DuQ0NvIHlEiatOafTndb3/7W3z22WfOyIVkxhsPU2vr00mP98feia0v3ofx8eHQeipx8LwFv1+5D/e/swUf/ZiF0qpaudMkImpUs3uiqqqqsGzZMvzwww/o27cvPD3t76/27rvvOiw5al1caJPkEhbgjdcf6YMZI6LwSVo2Pk07h+yiCry+/hjeTTmJJwZ2xjNDIhAR6CN3qkREkmYXUYcOHUL//v0BAEeOHLHbx3kMri2nqH44r0sAP6hIHh18NZj1i+743fCu+HLfBazYeQ6nC8qwYuc5fJJ2DiOigzDx7kgM4bwpImoDuE6UE7nSOlElVbXo++r3AIDDrz4AP63nLY4gcj4hBLafKsRHO7KwJfOnW031CPbDM3dH4JH+ofBWt2ilFiKiG3LqOlHkfhquzAvwUbOAojZDoVBgWPeOGNa9I85cLsMnO8/hvxnnkZlfijlfHsZfvzuOxwZ0wm/iwtHD6Cd3ukTUzjSpiHrsscewYsUK6HQ6PPbYYzeN/fLLLx2SGLWunCLOh6K27Y6Ovnj9kT54/oEeWLs3F//elY3sogp8kpaNT9KyMSjCH+PiwjGyjxFaTw+50yWidqBJRZRer5fmH+j1XBDPHXFSObkKvZcnfntPVzx7dyR2nCnEyl05SDmejz3nrmDPuSvw/9YTTwzsjN/EhSOSE9GJyIk4J8qJXGlO1J+/OoyV6TmYfl83vJDQQ+50iJolv6QKa/bkYtXuHFyyVEnbh9zRAaNjw9g7RUTNwjlR1CxSTxQX2iQXFKzT4o8jovD7e+/AlszLWJmejS0nL2PnmSLsPFMEv3UqPNw/FL8e2Bn9wwy8so+IHKLZRVR+fj5eeOEF6QbEP+/IslqtDkuOWg+H88gdqDyUMPUKhqlXMHLNFfhvxnn8N+M8LhRX4rP0HHyWnoOoIF/8OrYzHr2zMzr6aeROmYhcWLOH8x588EHk5ORg+vTpjd6A+JFHHnFogq7MVYbz6qw2RM9LRp1NYOfL9yPU4CV3SkQOY7MJ7DpbhLUZ57HxyCVU1doAAB5KBe7rEYRfx3bGfT2CoFY1+wYOROSmmvr53ewiys/PD9u3b5cW3KQbc5UiKtdcgXsWbobaQ4kTfxkJJe9XRm6qpKoW6w9ewtqMXOzPKZa267088VBMCBL7h2JQRAD/BojaOafNiQoLC7tuCI9cW8NQXucAL354kFvTaT3xm7gu+E1cF5wuKMXaveex7sAF5JdUY9XuHKzanYNOBi883C8UiXeGItrYdv/zQ0Tya3b/9aJFi/Dyyy/j3LlzTkiH5NBQRIVzPhS1I92C/DDnoZ7Y+fIIfPbbOIyO7Qw/jQoXiiuxdOsZjFy0HSMXbcOHW87gQnGl3OkSURvU7OE8f39/VFRUoK6uDt7e3tfdgNhsNjs0QVfmKsN5b248gaVbz2BCfDhee6SP3OkQyaaq1orNJwqw7sAFbD5xGTVWm7RvcEQAHoox4sGYEATrtDJmSUTO5rThvEWLFt1OXtQGNdzyJYw9UdTOaT098GBMCB6MCYGlohYbj1zCugMXkJ5lxu5z9Y/X1h9DbLg/HooJwYN9QmDUs6Aiaq+42KYTuUpP1MPv/4jDFyz45/hY/KJXsNzpELU5lyyV2HA4DxsOX0JG9hW7fVJBFWNEiJ5XthK5A6ddnXetqqoq1NTU2G1ry8VCa3OVIqrvq/9DSVUd/jdzGG/iSnQLlyyV2Hi1oNr7s4JqQBcDHooJQUJvI3t2iVyY04qo8vJyvPTSS/j8889RVFR03X4utvkTVyiiLBW16Pf69wCAY68nwFvNReyJmupmBVW00Q8P9ArGA72N6B2q4yrpRC6kqZ/fzb46b/bs2di0aRM+/PBDaDQaLF++HK+99hpCQ0Px6aeftijZJUuWICIiAlqtFnFxcdi9e/dN49euXYvo6GhotVrExMRgw4YNdvuFEJg/fz5CQkLg5eUFk8mEU6dO2cWYzWaMGzcOOp0OBoMBkyZNQllZmbQ/MzMT9913H4KDg6HVatG1a1fMnTsXtbW1LWpjW9VwZV5HPw0LKKJmCtF74dmhkfjvc0Owa84ILHi4F+7qGgAPpQIn8kqxeNNp/PL9H3H3m5uw4Osj+PFUIWqvmaxORC5ONFNYWJjYvHmzEEIIPz8/cerUKSGEEJ9++ql48MEHm3s6sXr1aqFWq8VHH30kjh49KiZPniwMBoPIz89vNH7Hjh3Cw8NDLFy4UBw7dkzMnTtXeHp6isOHD0sxb775ptDr9WLdunXi4MGD4le/+pWIjIwUlZWVUszIkSNFv379xK5du8T27dtFt27dxNixY6X9Z86cER999JE4cOCAOHfunPj6669FUFCQmDNnTpPbZrFYBABhsVia/bq0lm8PXhDhL60Xj32wQ+5UiNyGuaxa/Hdvrpj66V4RPXejCH9pvfSIWZAs/rhqn1h/8KIoraqVO1UiakRTP7+bPZzn6+uLY8eOoUuXLujcuTO+/PJLDB48GFlZWYiJibHrzWmKuLg4DBo0CP/4xz8AADabDWFhYfjDH/6Al19++br4MWPGoLy8HOvXr5e23XXXXejfvz+WLl0KIQRCQ0Px/PPP44UXXgAAWCwWBAcHY8WKFXjyySdx/Phx9OrVC3v27EFsbCwAIDk5GQ899BDOnz+P0NDQRnOdNWsW9uzZg+3btzepba4wnPfBltNYmJyJR+/shL+P6S93OkRup6rWih2nC5FyLB8/HM9HYdlP80g9PRQYFBGA+6ODcG+PINzR0YfDfkRtgNOG87p27YqsrCwAQHR0ND7//HMAwLfffguDwdCsc9XU1CAjIwMmk+mnhJRKmEwmpKWlNXpMWlqaXTwAJCQkSPFZWVnIy8uzi9Hr9YiLi5Ni0tLSYDAYpAIKAEwmE5RKJdLT0xt93tOnTyM5ORnDhw+/YXuqq6tRUlJi92jrcnnjYSKn0np6YETPYLz5eF+kv2LCF8/FY+rwruga6INaq8DOM0V447vjML27FcPe2oz5Xx/B5hMFqKzh/FKitq7Zk2AmTpyIgwcPYvjw4Xj55Zfx8MMP4x//+Adqa2vx7rvvNutchYWFsFqtCA62v6w+ODgYJ06caPSYvLy8RuPz8vKk/Q3bbhYTFBRkt1+lUiEgIECKaTBkyBDs27cP1dXVmDJlCl5//fUbticpKQmvvfbaDfe3RdlFLKKIWouHUoGB4QEYGB6AOQ/2RFZhObZkFmBz5mXsOluEXHMlPk3Lxqdp2dColIi/owPu6xGE+3oEoUsH/o0StTXNLqL+9Kc/Sd+bTCacOHECGRkZ6NatG/r27evQ5NqCNWvWoLS0FAcPHsSLL76It99+G7Nnz240ds6cOZg1a5b0c0lJCcLCwlor1RZpmFjOf6CJWl9koA8iAyMx8e5IVNTUYefpImzOLMCWzMu4UFyJLZmXsSXzMhbgKLp29MGwqI4Y2i0Qd93RAb4aXghCJLdm/RXW1tZi5MiRWLp0KaKiogAA4eHhCA8Pb9GTBwYGwsPDA/n5+Xbb8/PzYTQaGz3GaDTeNL7ha35+PkJCQuxi+vfvL8UUFBTYnaOurg5ms/m6520ognr16gWr1YopU6bg+eefh4eHx3W5aTQaaDSaWzW7zaips+Hi1XuC8b55RPLyVqtg6hUMU69gCCFwqqAMm08UYNOJAuzNvoKzl8tx9nI5Vuw8B5VSgQFd/DE0KhBDowLRt5MeKo9mz84gotvUrL86T09PHDp0yGFPrlarMXDgQKSmpkrbbDYbUlNTER8f3+gx8fHxdvEAkJKSIsVHRkbCaDTaxZSUlCA9PV2KiY+PR3FxMTIyMqSYTZs2wWazIS4u7ob52mw21NbWwmZzj0uULxZXwiYAjUqJjn6uU/wRuTuFQoHuwX6YOvwOrJkaj/3zf4GlTw3AuLgu6BLgjTqbwO5zZrybchKPfbATd/4lBVP/vRf/3pWN7KJyudMnajea3R/81FNP4V//+hfefPNNhyQwa9YsTJgwAbGxsRg8eDAWLVqE8vJyTJw4EQAwfvx4dOrUCUlJSQCAGTNmYPjw4XjnnXcwatQorF69Gnv37sWyZcsA1P/jM3PmTLzxxhuIiopCZGQk5s2bh9DQUCQmJgIAevbsiZEjR2Ly5MlYunQpamtrMX36dDz55JPSlXkrV66Ep6cnYmJioNFosHfvXsyZMwdjxoy57qbLrirnmknlvCKIqO3SaT0xsk8IRvap713PKarA9tOX8eOpQuw4XVh/x4Gj+fjf0fpe+rAALwzt1hHxd3TAXV0DEOTH+/sROUOzi6i6ujp89NFH+OGHHzBw4ED4+PjY7W/u5PIxY8bg8uXLmD9/PvLy8tC/f38kJydLE8NzcnKgVP7UYTZkyBB89tlnmDt3Ll555RVERUVh3bp16NOnjxQze/ZslJeXY8qUKSguLsbQoUORnJwMrfanf0hWrlyJ6dOnY8SIEVAqlXj88cexePFiab9KpcLf/vY3nDx5EkIIhIeHY/r06XZzwlxd9tUiKpzzoYhcSpcO3hjXIRzj4sJhtQkcvmDB9pOXsf10IfbnXEGuuRKrdudg1e4cAEC3IF/c1TUA8V0DEdc1AIG+7HkmcoRmrxN133333fhkCgU2bdp020m5i7a+TtRfNxzHsm1nMfHuCCx4uLfc6RCRA5RX1yE9qwg/nirCrrNFOJ5Xgp//K9892Bd3de2A+K4dENe1AwJ81PIkS9RGNfXzu9k9UZs3b76txKjtyOHyBkRux0ejwv3Rwbg/ur43v7iiBulZZqSdqS+qTuSV4mR+GU7ml+HTtGwA9ff5u6tr/dDfwPAAzpEkaqIWXyN7+vRpnDlzBsOGDYOXlxeEEJxX42I4nEfk/gzeaiT0NiKhd/2Vx+byGqSfrS+o0s4W4WR+GU7kleJEXilW7DwHAOga6IPYCH/ERgRgUEQAIjpw3iRRY5pdRBUVFWH06NHYvHkzFAoFTp06ha5du2LSpEnw9/fHO++844w8ycGEEFytnKgdCvBR48GYEDwYUz9JvbCsGulnzUg7W4g9WVeQmV+Ks4XlOFtYjs/3ngcABPpqMEgqqvzRK0THJRWI0MLFNj09PZGTk4OePXtK28eMGYNZs2axiHIRVypqUVZdBwDo7M8iiqi9CvTVYFTfEIzqW19UFVfUYF/OFew5dwV7z5lxMNeCwrJqbDySh41H6u/o4K32wJ1dDIgNr++p6t/FwMU/qV1q9m/9999/j//973/o3Lmz3faoqChkZ2c7LDFyroa1ZIw6LbSe1y8cSkTtk8FbbTenqqrWisMXLNhzzoy9Vwurkqo67DhdhB2niwAACgXQI9gPd3Yx4M4wf9zZxYA7OvpCqeQQILm3ZhdR5eXl8Pa+vufCbDa71Grd7V0Oh/KIqAm0nh4YdHVuFADYbPWrqdcXVWbsOXcFF4orpXlVq3bnAgD8NCr072LAnWEG3NnFH/3DDPDnVYDkZppdRN1zzz349NNP8Ze//AVA/bIGNpsNCxcuvOnyB9S2NMyHCmMRRUTNoFQq0MPohx5GPzx1V/0tvwpKqrA/txj7c4qxP+cKDp23oLS6DttPFWL7qULp2MhAn6tFlQH9w/wRHeIHT86tIhfW7CJq4cKFGDFiBPbu3YuamhrMnj0bR48ehdlsxo4dO5yRIzlBdhGvzCMixwjSae2uAKyz2pCZX3q1qCrG/tz6e/9lFdY/vtx/AQCgVinRK0SHvp31iOmkR9/OBnQL8oUHhwHJRTS7iOrTpw9OnjyJf/zjH/Dz80NZWRkee+wxTJs2ze6Gv9S2cTiPiJxF5aFE71A9eofqpd6q4ooaHGjorcotxoGcKyipqsOB3GIcyC2WjvXy9ECfTjrEdDLUF1ed9Yjs4MP5VdQmtehyCr1ejz//+c92286fP48pU6ZI97Cjtk1a3oA9UUTUCgzeatzbIwj39ggCUD+3KsdcgUMXLDiUW4xDFyw4esGC8hor9pyrvzqwga9GhT6ddOjb2XC1x0rPe35Sm9Ds277cyMGDBzFgwABYrVZHnM4ttNXbvlTXWRE9LxlCAHvnmngfLSJqE6w2gazCMhw6b8Gh8xYcvmDB0YsWVNXarov106rQK0SH3qF69ArVoXeoDt2CfDnHihzCabd9Idd3/kolhKhf66UDr5YhojbCQ6lAtyA/dAvyw2MD6pfRqbPacPpyfWF1+LwFhy5YcPxiCUqr6pCeZUZ6llk6Xu2hRHejr11x1TNExzWsyGn4m9UOXTsfit3hRNSWqTyUiDbqEG3UYXRsGACgps6G0wVlOHapBEcvWnDsYgmOXaovrI5cKMGRCyUAzkvniOjgLRVV9QWWDh39NPz3j24bi6h2iDceJiJXplYp6wuiUB2eGFjfYyWEwPkrlVJRdfRqYXXJUoVzRRU4V1SB7w5fks7RwUctLdUQbfRDD6MO3YN94a3mxyI1XZN/Wx577LGb7i8uLr7dXKiV8Mo8InI3CoUCYQHeCAvwxsg+P10pbi6vudpTZakvrC6W4MzlMhSV12DnmSLsPFN0zTnq/13sEfxTYdXD6IeIDt68VyA1qslFlF6vv+X+8ePH33ZC5HwNRRTXiCIidxfgo8bQqEAMjQqUtlXWWHGqoH6F9cyrjxN5pSgsq0Z2UQWyiyrw/bF8KV6tUiIqyNeu1yra6IcgDgm2e00uoj7++GNn5kGtqGE4j6uVE1F75KX2QN/OBvTtbLDbXlRWLRVUmXmlOJFfipN5paisteLo1SHCa+m9PBEV5IuoYF/c0dEXUcF+iAryRYhey+KqneDgbzsjhOBwHhFRIzr4ajCkmwZDuv3Ua2WzCeReqfhZr1UJsgrLYamsxd7sK9ibfcXuPD5qD3QL8kW3ID9EBfsiKsgX3YJ80dnfm6uxuxkWUe3M5bJqVNZaoVAAnf1ZRBER3YxSqUB4Bx+Ed/CRbmsDAFW1Vpy9XI5TBaU4U1CGU1cf5wrLUV5jxcHzFhw8b7E7l0alvNpj5YtuDV+D/BDewZvrW7koFlHtTMNK5aF6L6hV/KMlImoJraeHdIXgtWrqbMguKsfpawqrU/mlOFtYjuo6G45dqr9q8FoqpQJdOnija6Avunb0QddAH3TtWP99Bx81hwbbMBZR7UzDUF5YgJfMmRARuR+1Slk/NyrYDw9es91qE8g1V1wtrEpxuqBMelTU1Pdqnb1cDhy3P59Oq0JkR1/cEehTX2B19EVkoA8iA32g9fRo1bbR9VhEtTPZVyeVhwf4yJwJEVH74aFUICLQBxGBPvhFr2Bpu80mkFdSVV9EFZZd/VqOs5fLcKG4EiVVdTiYW4yD19ykGahfjiFU74WuHX1wx9XCqqHICtFpecPmVsIiqp3J4Y2HiYjaDKVSgVCDF0INXnbLMAD1867OFZUj62phdeZyGbIK63usLJW1uFBciQvFldh+qtDuOLVKiS4B3ojo4I3wDj7XfPVBqEHLNa8ciEVUO5Nr5vIGRESuQOvpId3y5lpCCJjLa3C2sL7AOtPQg3W5DDnmCum2OKcLyq47p0qpQGd/L/viKrD+a5i/N+fKNhOLqHbmp+E8FlFERK5IoVCgg68GHXw1GBQRYLfPahO4WFyJ7KIKnCsqR3ZROc4VVSC7qBzZRRWorrNJt8HZ+rPzKhVAqMELER18EN7B++qj/vswf2/48EbO1+Er0o5U1lhRUFoNgGtEERG5Iw/lT7e/+fnwoM0mkF9ahXOFFXbFVcPXihorzl+pxPkrlfjx9PXnDvBRI8zfSzp/mL83wgK80CXAG6EGr3a5TAOLqHbk/JX6Xig/jQoGb0+ZsyEiotakVCoQovdCiN4L8Xd0sNsnhMDlq7e9OVdY32uVba7/PsdcAUtlLczlNTCX11y3/hVQ34sVovdCZ//6oqq+0PJCmL83ugR4o6Ob3iKHRVQ70jCU16WDt1v+MhMRUcsoFAoE+WkR5Ke9bogQAEqqapFrrkCuubL+65WKq1/rf66us0kT3dOzzNcdr1Ep0flqL1aXq71Ynf290MnfC50MXghw0fWwWES1I7zdCxERtYRO64neoXr0DtVft08Igcul1VcLq/qiKkcqtCpxyVKJ6jobzlwux5nL5Y2e38vTA6EGLTr5e6OTob5Hq5PhpyIrWKdtk7fMYRHVjrCIIiIiR1MoFAjSaRGk02Jg+PX7a602XCyurC+wrunBOn+lAheuVKKgtP52ZDcrslRKBUIM2vrCyuCNTv5e6Hy1yIqN8IdGJc/Coyyi2hGuEUVERK3N00Mp3X+wMdV1VlwqrqofDrxSifNXv14orsCF4kpcKq5CnU1c7eWqBGA/XHjo1QdYRJHzsSeKiIjaGo3KQ1rNvTFWm0BBaRXOX2koruqvILxQXAlLRQ10WvkulGIR1U7Yrt63CeAtX4iIyHV4XHNV4aAIubOx1/4WdWinCkqrUV1nq/9lNGjlToeIiMjlsYhqJxqG8kIN2na5IBoREZGj8dO0ncjhUB4REZFDsYhqJ3KK6i8b5Y2HiYiIHKNNFFFLlixBREQEtFot4uLisHv37pvGr127FtHR0dBqtYiJicGGDRvs9gshMH/+fISEhMDLywsmkwmnTp2yizGbzRg3bhx0Oh0MBgMmTZqEsrKf7ni9ZcsWPPLIIwgJCYGPjw/69++PlStXOq7RrYxX5hERETmW7EXUmjVrMGvWLCxYsAD79u1Dv379kJCQgIKCgkbjd+7cibFjx2LSpEnYv38/EhMTkZiYiCNHjkgxCxcuxOLFi7F06VKkp6fDx8cHCQkJqKqqkmLGjRuHo0ePIiUlBevXr8e2bdswZcoUu+fp27cvvvjiCxw6dAgTJ07E+PHjsX79eue9GE4kDedxjSgiIiKHUAghhJwJxMXFYdCgQfjHP/4BALDZbAgLC8Mf/vAHvPzyy9fFjxkzBuXl5XbFzF133YX+/ftj6dKlEEIgNDQUzz//PF544QUAgMViQXBwMFasWIEnn3wSx48fR69evbBnzx7ExsYCAJKTk/HQQw/h/PnzCA0NbTTXUaNGITg4GB999FGT2lZSUgK9Xg+LxQKdTtes18XRYt9IQWFZDdb/YSj6dLp+2X4iIiKq19TPb1l7ompqapCRkQGTySRtUyqVMJlMSEtLa/SYtLQ0u3gASEhIkOKzsrKQl5dnF6PX6xEXFyfFpKWlwWAwSAUUAJhMJiiVSqSnp98wX4vFgoCA62/M2KC6uholJSV2j7agvLoOhWU1ADgnioiIyFFkLaIKCwthtVoRHBxstz04OBh5eXmNHpOXl3fT+Iavt4oJCgqy269SqRAQEHDD5/3888+xZ88eTJw48YbtSUpKgl6vlx5hYWE3jG1NuVfqh/IM3p7Qe8m3sisREZE7kX1OlCvYvHkzJk6ciH/+85/o3bv3DePmzJkDi8UiPXJzc1sxyxvLLuKkciIiIkeTtYgKDAyEh4cH8vPz7bbn5+fDaDQ2eozRaLxpfMPXW8X8fOJ6XV0dzGbzdc+7detWPPzww/j73/+O8ePH37Q9Go0GOp3O7tEWNNzuhUN5REREjiNrEaVWqzFw4ECkpqZK22w2G1JTUxEfH9/oMfHx8XbxAJCSkiLFR0ZGwmg02sWUlJQgPT1diomPj0dxcTEyMjKkmE2bNsFmsyEuLk7atmXLFowaNQp/+9vf7K7cczUNPVHhLKKIiIgcRvYbEM+aNQsTJkxAbGwsBg8ejEWLFqG8vFyaezR+/Hh06tQJSUlJAIAZM2Zg+PDheOeddzBq1CisXr0ae/fuxbJlywAACoUCM2fOxBtvvIGoqChERkZi3rx5CA0NRWJiIgCgZ8+eGDlyJCZPnoylS5eitrYW06dPx5NPPildmbd582b88pe/xIwZM/D4449Lc6XUavVNJ5e3RVwjioiIyAlEG/D++++LLl26CLVaLQYPHix27dol7Rs+fLiYMGGCXfznn38uunfvLtRqtejdu7f47rvv7PbbbDYxb948ERwcLDQajRgxYoTIzMy0iykqKhJjx44Vvr6+QqfTiYkTJ4rS0lJp/4QJEwSA6x7Dhw9vcrssFosAICwWS9NfDCe4763NIvyl9WLHqcuy5kFEROQKmvr5Lfs6Ue6sLawTZbUJRM/biFqrwI8v3YfO/uyNIiIiuhmXWCeKnC+vpAq1VgGVUoEQvZfc6RAREbkNFlFuLufqpPLO/l7wUCpkzoaIiMh9sIhycznmcgBAlw4+MmdCRETkXlhEubmfrszjUB4REZEjsYhycznmSgBc3oCIiMjRWES5uZyiq8N5ARzOIyIiciQWUW6OC20SERE5B4soN1ZSVYsrFbUAgC4dWEQRERE5EosoN9awvEEHHzV8NbLf4YeIiMitsIhyY7lXh/LCOJRHRETkcCyi3FjDfKhwDuURERE5HIsoN5bNSeVEREROwyLKjXE4j4iIyHlYRLkxaTiPRRQREZHDsYhyU3VWGy5cubpaOedEERERORyLKDd1yVKFOpuAWqVEsJ9W7nSIiIjcDosoN9UwlBfm7wWlUiFzNkRERO6HRZSbyi7ilXlERETOxCLKTfGeeURERM7FIspN5ZjLAQBdOvjInAkREZF7YhHlptgTRURE5FwsotxUDudEERERORWLKDdUXFGDkqo6ACyiiIiInIVFlBtqGMrr6KeBl9pD5myIiIjcE4soN8T5UERERM7HIsoNNawRxXvmEREROQ+LKDeU27BaOYsoIiIip2ER5YY4nEdEROR8LKLckDSc14FFFBERkbOwiHIzNXU2XLJUAmBPFBERkTOxiHIzF4srYROA1lOJjn4audMhIiJyWyyi3Ez2NfOhFAqFzNkQERG5LxZRboaTyomIiFoHiyg3kysVUT4yZ0JEROTeWES5meyicgBAlwAvmTMhIiJybyyi3EyO+eqVeVzegIiIyKlYRLkRIQSH84iIiFqJ7EXUkiVLEBERAa1Wi7i4OOzevfum8WvXrkV0dDS0Wi1iYmKwYcMGu/1CCMyfPx8hISHw8vKCyWTCqVOn7GLMZjPGjRsHnU4Hg8GASZMmoaysTNpfVVWFZ555BjExMVCpVEhMTHRYe53JXF6Dsuo6AEBnfw7nEREROZOsRdSaNWswa9YsLFiwAPv27UO/fv2QkJCAgoKCRuN37tyJsWPHYtKkSdi/fz8SExORmJiII0eOSDELFy7E4sWLsXTpUqSnp8PHxwcJCQmoqqqSYsaNG4ejR48iJSUF69evx7Zt2zBlyhRpv9VqhZeXF/74xz/CZDI57wVwsIYr84w6LbSeHjJnQ0RE5OaEjAYPHiymTZsm/Wy1WkVoaKhISkpqNH706NFi1KhRdtvi4uLE1KlThRBC2Gw2YTQaxVtvvSXtLy4uFhqNRqxatUoIIcSxY8cEALFnzx4pZuPGjUKhUIgLFy5c95wTJkwQjzzySIvaZ7FYBABhsVhadHxzrdt/XoS/tF78eunOVnk+IiIid9TUz2/ZeqJqamqQkZFh19OjVCphMpmQlpbW6DFpaWnX9QwlJCRI8VlZWcjLy7OL0ev1iIuLk2LS0tJgMBgQGxsrxZhMJiiVSqSnp99Wm6qrq1FSUmL3aE05RVwjioiIqLXIVkQVFhbCarUiODjYbntwcDDy8vIaPSYvL++m8Q1fbxUTFBRkt1+lUiEgIOCGz9tUSUlJ0Ov10iMsLOy2ztdcXGiTiIio9cg+sdydzJkzBxaLRXrk5ua26vM3FFHhXN6AiIjI6WQrogIDA+Hh4YH8/Hy77fn5+TAajY0eYzQabxrf8PVWMT+fuF5XVwez2XzD520qjUYDnU5n92hNDUVUGHuiiIiInE62IkqtVmPgwIFITU2VttlsNqSmpiI+Pr7RY+Lj4+3iASAlJUWKj4yMhNFotIspKSlBenq6FBMfH4/i4mJkZGRIMZs2bYLNZkNcXJzD2tfaqmqtyCupvwKRw3lERETOp5LzyWfNmoUJEyYgNjYWgwcPxqJFi1BeXo6JEycCAMaPH49OnTohKSkJADBjxgwMHz4c77zzDkaNGoXVq1dj7969WLZsGQBAoVBg5syZeOONNxAVFYXIyEjMmzcPoaGh0lpPPXv2xMiRIzF58mQsXboUtbW1mD59Op588kmEhoZKuR07dgw1NTUwm80oLS3FgQMHAAD9+/dvtdenOc5fqYQQgI/aAx181HKnQ0RE5PZkLaLGjBmDy5cvY/78+cjLy0P//v2RnJwsTQzPycmBUvlTZ9mQIUPw2WefYe7cuXjllVcQFRWFdevWoU+fPlLM7NmzUV5ejilTpqC4uBhDhw5FcnIytFqtFLNy5UpMnz4dI0aMgFKpxOOPP47Fixfb5fbQQw8hOztb+vnOO+8EUL+YZ1uUe81QnkKhkDkbIiIi96cQbbUqcAMlJSXQ6/WwWCxOnx/1yc5zWPDNUTzQKxjLxsfe+gAiIiJqVFM/v3l1npvILuKVeURERK2JRZSb4BpRRERErYtFlJvI5fIGRERErYpFlBsQQlyz0KaPzNkQERG1Dyyi3MDlsmpU1lqhUACdDF5yp0NERNQusIhyAw1DeaF6L6hVfEuJiIhaAz9x3UDDlXmcVE5ERNR6WES5AV6ZR0RE1PpYRLkBqYjiGlFERESthkWUG8jhcB4REVGrYxHlBjicR0RE1PpYRLm4yhorCkqrAfCWL0RERK2JRZSLy71S3wvlp1VB7+UpczZERETtB4soF3ftfCiFQiFzNkRERO0HiygX99PtXjiUR0RE1JpYRLm4HN54mIiISBYsolwcr8wjIiKSB4soFycN5wX4yJwJERFR+8IiyoXZbII9UURERDJhEeXCCkqrUVNng4dSgRCDVu50iIiI2hUWUS4su6gcANDJ4AVPD76VRERErYmfvC6MQ3lERETyYRHlwnK5vAEREZFsWES5sGwutElERCQbFlEujMN5RERE8mER5cJyWUQRERHJhkWUiyqrrkNhWQ0AoAuH84iIiFodiygX1dALZfD2hE7rKXM2RERE7Q+LKBfF+VBERETyYhHlonKKWEQRERHJiUWUi2JPFBERkbxYRLkoFlFERETyYhHloqQiilfmERERyYJFlAuy2gTOX2FPFBERkZxYRLmgvJIq1FoFPD0UCNF7yZ0OERFRu8QiygVlF5UDADr7e8NDqZA5GyIiovaJRZQLalhoM4xDeURERLJpE0XUkiVLEBERAa1Wi7i4OOzevfum8WvXrkV0dDS0Wi1iYmKwYcMGu/1CCMyfPx8hISHw8vKCyWTCqVOn7GLMZjPGjRsHnU4Hg8GASZMmoayszC7m0KFDuOeee6DVahEWFoaFCxc6psG3qWFSeTiLKCIiItnIXkStWbMGs2bNwoIFC7Bv3z7069cPCQkJKCgoaDR+586dGDt2LCZNmoT9+/cjMTERiYmJOHLkiBSzcOFCLF68GEuXLkV6ejp8fHyQkJCAqqoqKWbcuHE4evQoUlJSsH79emzbtg1TpkyR9peUlOCBBx5AeHg4MjIy8NZbb+HVV1/FsmXLnPdiNFE2F9okIiKSn5DZ4MGDxbRp06SfrVarCA0NFUlJSY3Gjx49WowaNcpuW1xcnJg6daoQQgibzSaMRqN46623pP3FxcVCo9GIVatWCSGEOHbsmAAg9uzZI8Vs3LhRKBQKceHCBSGEEB988IHw9/cX1dXVUsxLL70kevTo0eS2WSwWAUBYLJYmH9MUv3p/uwh/ab3YePiSQ89LRERETf/8lrUnqqamBhkZGTCZTNI2pVIJk8mEtLS0Ro9JS0uziweAhIQEKT4rKwt5eXl2MXq9HnFxcVJMWloaDAYDYmNjpRiTyQSlUon09HQpZtiwYVCr1XbPk5mZiStXrjSaW3V1NUpKSuweziAN53GNKCIiItnIWkQVFhbCarUiODjYbntwcDDy8vIaPSYvL++m8Q1fbxUTFBRkt1+lUiEgIMAuprFzXPscP5eUlAS9Xi89wsLCGm/4baissUKtqn/bOLGciIhIPrLPiXInc+bMgcVikR65ubkOfw4vtQfSXzHhxF9Gwlejcvj5iYiIqGlkLaICAwPh4eGB/Px8u+35+fkwGo2NHmM0Gm8a3/D1VjE/n7heV1cHs9lsF9PYOa59jp/TaDTQ6XR2D2fReno47dxERER0a7IWUWq1GgMHDkRqaqq0zWazITU1FfHx8Y0eEx8fbxcPACkpKVJ8ZGQkjEajXUxJSQnS09OlmPj4eBQXFyMjI0OK2bRpE2w2G+Li4qSYbdu2oba21u55evToAX9//9tsOREREbm8VprofkOrV68WGo1GrFixQhw7dkxMmTJFGAwGkZeXJ4QQ4umnnxYvv/yyFL9jxw6hUqnE22+/LY4fPy4WLFggPD09xeHDh6WYN998UxgMBvH111+LQ4cOiUceeURERkaKyspKKWbkyJHizjvvFOnp6eLHH38UUVFRYuzYsdL+4uJiERwcLJ5++mlx5MgRsXr1auHt7S3+7//+r8ltc9bVeUREROQ8Tf38lr2IEkKI999/X3Tp0kWo1WoxePBgsWvXLmnf8OHDxYQJE+ziP//8c9G9e3ehVqtF7969xXfffWe332aziXnz5ong4GCh0WjEiBEjRGZmpl1MUVGRGDt2rPD19RU6nU5MnDhRlJaW2sUcPHhQDB06VGg0GtGpUyfx5ptvNqtdLKKIiIhcT1M/vxVCCCFvX5j7KikpgV6vh8Vicer8KCIiInKcpn5+8+o8IiIiohZgEUVERETUAiyiiIiIiFqARRQRERFRC7CIIiIiImoBFlFERERELcAiioiIiKgFWEQRERERtQCLKCIiIqIWUMmdgDtrWAy+pKRE5kyIiIioqRo+t291UxcWUU5UWloKAAgLC5M5EyIiImqu0tJS6PX6G+7nvfOcyGaz4eLFi/Dz84NCoXDYeUtKShAWFobc3Fy3vCefu7cPcP82unv7APdvI9vn+ty9jc5snxACpaWlCA0NhVJ545lP7IlyIqVSic6dOzvt/Dqdzi3/MBq4e/sA92+ju7cPcP82sn2uz93b6Kz23awHqgEnlhMRERG1AIsoIiIiohZgEeWCNBoNFixYAI1GI3cqTuHu7QPcv43u3j7A/dvI9rk+d29jW2gfJ5YTERERtQB7ooiIiIhagEUUERERUQuwiCIiIiJqARZRRERERC3AIsoFLVmyBBEREdBqtYiLi8Pu3bvlTuk6r776KhQKhd0jOjpa2l9VVYVp06ahQ4cO8PX1xeOPP478/Hy7c+Tk5GDUqFHw9vZGUFAQXnzxRdTV1dnFbNmyBQMGDIBGo0G3bt2wYsUKp7Rn27ZtePjhhxEaGgqFQoF169bZ7RdCYP78+QgJCYGXlxdMJhNOnTplF2M2mzFu3DjodDoYDAZMmjQJZWVldjGHDh3CPffcA61Wi7CwMCxcuPC6XNauXYvo6GhotVrExMRgw4YNrdLGZ5555rr3dOTIkS7TxqSkJAwaNAh+fn4ICgpCYmIiMjMz7WJa8/fS0X/HTWnfvffee917+Lvf/c4l2vfhhx+ib9++0sKK8fHx2Lhxo7Tfld+7prbRld+/xrz55ptQKBSYOXOmtM3l3kdBLmX16tVCrVaLjz76SBw9elRMnjxZGAwGkZ+fL3dqdhYsWCB69+4tLl26JD0uX74s7f/d734nwsLCRGpqqti7d6+46667xJAhQ6T9dXV1ok+fPsJkMon9+/eLDRs2iMDAQDFnzhwp5uzZs8Lb21vMmjVLHDt2TLz//vvCw8NDJCcnO7w9GzZsEH/+85/Fl19+KQCIr776ym7/m2++KfR6vVi3bp04ePCg+NWvfiUiIyNFZWWlFDNy5EjRr18/sWvXLrF9+3bRrVs3MXbsWGm/xWIRwcHBYty4ceLIkSNi1apVwsvLS/zf//2fFLNjxw7h4eEhFi5cKI4dOybmzp0rPD09xeHDh53exgkTJoiRI0favadms9kupi23MSEhQXz88cfiyJEj4sCBA+Khhx4SXbp0EWVlZVJMa/1eOuPvuCntGz58uJg8ebLde2ixWFyifd9884347rvvxMmTJ0VmZqZ45ZVXhKenpzhy5IgQwrXfu6a20ZXfv5/bvXu3iIiIEH379hUzZsyQtrva+8giysUMHjxYTJs2TfrZarWK0NBQkZSUJGNW11uwYIHo169fo/uKi4uFp6enWLt2rbTt+PHjAoBIS0sTQtR/oCuVSpGXlyfFfPjhh0Kn04nq6mohhBCzZ88WvXv3tjv3mDFjREJCgoNbY+/nBYbNZhNGo1G89dZb0rbi4mKh0WjEqlWrhBBCHDt2TAAQe/bskWI2btwoFAqFuHDhghBCiA8++ED4+/tL7RNCiJdeekn06NFD+nn06NFi1KhRdvnExcWJqVOnOrWNQtQXUY888sgNj3G1NhYUFAgAYuvWrUKI1v29bI2/45+3T4j6D+FrP7B+zpXaJ4QQ/v7+Yvny5W733jXWRiHc5/0rLS0VUVFRIiUlxa5Nrvg+cjjPhdTU1CAjIwMmk0naplQqYTKZkJaWJmNmjTt16hRCQ0PRtWtXjBs3Djk5OQCAjIwM1NbW2rUjOjoaXbp0kdqRlpaGmJgYBAcHSzEJCQkoKSnB0aNHpZhrz9EQ09qvRVZWFvLy8uxy0ev1iIuLs2uPwWBAbGysFGMymaBUKpGeni7FDBs2DGq1WopJSEhAZmYmrly5IsXI2eYtW7YgKCgIPXr0wHPPPYeioiJpn6u10WKxAAACAgIAtN7vZWv9Hf+8fQ1WrlyJwMBA9OnTB3PmzEFFRYW0z1XaZ7VasXr1apSXlyM+Pt7t3rvG2tjAHd6/adOmYdSoUdfl4YrvI29A7EIKCwthtVrtfnkAIDg4GCdOnJApq8bFxcVhxYoV6NGjBy5duoTXXnsN99xzD44cOYK8vDyo1WoYDAa7Y4KDg5GXlwcAyMvLa7SdDftuFlNSUoLKykp4eXk5qXX2GvJpLJdrcw0KCrLbr1KpEBAQYBcTGRl53Tka9vn7+9+wzQ3ncKaRI0fiscceQ2RkJM6cOYNXXnkFDz74INLS0uDh4eFSbbTZbJg5cybuvvtu9OnTR3r+1vi9vHLlitP/jhtrHwD85je/QXh4OEJDQ3Ho0CG89NJLyMzMxJdffukS7Tt8+DDi4+NRVVUFX19ffPXVV+jVqxcOHDjgNu/djdoIuP77BwCrV6/Gvn37sGfPnuv2ueLfIIsocooHH3xQ+r5v376Ii4tDeHg4Pv/881YrbsixnnzySen7mJgY9O3bF3fccQe2bNmCESNGyJhZ802bNg1HjhzBjz/+KHcqTnGj9k2ZMkX6PiYmBiEhIRgxYgTOnDmDO+64o7XTbLYePXrgwIEDsFgs+O9//4sJEyZg69atcqflUDdqY69evVz+/cvNzcWMGTOQkpICrVYrdzoOweE8FxIYGAgPD4/rrlTIz8+H0WiUKaumMRgM6N69O06fPg2j0YiamhoUFxfbxVzbDqPR2Gg7G/bdLEan07VqodaQz83eF6PRiIKCArv9dXV1MJvNDmmzHO9/165dERgYiNOnT0u5uUIbp0+fjvXr12Pz5s3o3LmztL21fi+d/Xd8o/Y1Ji4uDgDs3sO23D61Wo1u3bph4MCBSEpKQr9+/fDee++5zXt3szY2xtXev4yMDBQUFGDAgAFQqVRQqVTYunUrFi9eDJVKheDgYJd7H1lEuRC1Wo2BAwciNTVV2maz2ZCammo3Zt4WlZWV4cyZMwgJCcHAgQPh6elp147MzEzk5ORI7YiPj8fhw4ftPpRTUlKg0+mkru34+Hi7czTEtPZrERkZCaPRaJdLSUkJ0tPT7dpTXFyMjIwMKWbTpk2w2WzSP4Tx8fHYtm0bamtrpZiUlBT06NED/v7+UkxbaDMAnD9/HkVFRQgJCZFya8ttFEJg+vTp+Oqrr7Bp06brhhVb6/fSWX/Ht2pfYw4cOAAAdu9hW21fY2w2G6qrq13+vWtKGxvjau/fiBEjcPjwYRw4cEB6xMbGYty4cdL3Lvc+NmsaOslu9erVQqPRiBUrVohjx46JKVOmCIPBYHelQlvw/PPPiy1btoisrCyxY8cOYTKZRGBgoCgoKBBC1F/G2qVLF7Fp0yaxd+9eER8fL+Lj46XjGy5jfeCBB8SBAwdEcnKy6NixY6OXsb744ovi+PHjYsmSJU5b4qC0tFTs379f7N+/XwAQ7777rti/f7/Izs4WQtQvcWAwGMTXX38tDh06JB555JFGlzi48847RXp6uvjxxx9FVFSU3eX/xcXFIjg4WDz99NPiyJEjYvXq1cLb2/u6y/9VKpV4++23xfHjx8WCBQsctsTBzdpYWloqXnjhBZGWliaysrLEDz/8IAYMGCCioqJEVVWVS7TxueeeE3q9XmzZssXuEvGKigopprV+L53xd3yr9p0+fVq8/vrrYu/evSIrK0t8/fXXomvXrmLYsGEu0b6XX35ZbN26VWRlZYlDhw6Jl19+WSgUCvH9998LIVz7vWtKG139/buRn19x6GrvI4soF/T++++LLl26CLVaLQYPHix27dold0rXGTNmjAgJCRFqtVp06tRJjBkzRpw+fVraX1lZKX7/+98Lf39/4e3tLR599FFx6dIlu3OcO3dOPPjgg8LLy0sEBgaK559/XtTW1trFbN68WfTv31+o1WrRtWtX8fHHHzulPZs3bxYArntMmDBBCFG/zMG8efNEcHCw0Gg0YsSIESIzM9PuHEVFRWLs2LHC19dX6HQ6MXHiRFFaWmoXc/DgQTF06FCh0WhEp06dxJtvvnldLp9//rno3r27UKvVonfv3uK7775zehsrKirEAw88IDp27Cg8PT1FeHi4mDx58nX/4LTlNjbWNgB2vzOt+Xvp6L/jW7UvJydHDBs2TAQEBAiNRiO6desmXnzxRbt1htpy+5599lkRHh4u1Gq16NixoxgxYoRUQAnh2u9dU9ro6u/fjfy8iHK191EhhBDN67siIiIiIs6JIiIiImoBFlFERERELcAiioiIiKgFWEQRERERtQCLKCIiIqIWYBFFRERE1AIsooiIiIhagEUUERERUQuwiCIiuioiIgKLFi2SOw0ichEsoojI5SgUips+Xn311Radd8+ePZgyZYpjk73Gvffei5kzZzrt/ETUulRyJ0BE1FyXLl2Svl+zZg3mz5+PzMxMaZuvr6/0vRACVqsVKtWt/7nr2LGjYxMlIrfGnigicjlGo1F66PV6KBQK6ecTJ07Az88PGzduxMCBA6HRaPDjjz/izJkzeOSRRxAcHAxfX18MGjQIP/zwg915fz6cp1AosHz5cjz66KPw9vZGVFQUvvnmm5vm9sEHHyAqKgparRbBwcF44oknAADPPPMMtm7divfee0/qMTt37hwA4MiRI3jwwQfh6+uL4OBgPP300ygsLJTOee+992L69OmYPn069Ho9AgMDMW/ePPDWp0TyYhFFRG7p5Zdfxptvvonjx4+jb9++KCsrw0MPPYTU1FTs378fI0eOxMMPP4ycnJybnue1117D6NGjcejQITz00EMYN24czGZzo7F79+7FH//4R7z++uvIzMxEcnIyhg0bBgB47733EB8fj8mTJ+PSpUu4dOkSwsLCUFxcjPvvvx933nkn9u7di+TkZOTn52P06NF25/7kk0+gUqmwe/duvPfee3j33XexfPlyx7xYRNQygojIhX388cdCr9dLP2/evFkAEOvWrbvlsb179xbvv/++9HN4eLj4+9//Lv0MQMydO1f6uaysTAAQGzdubPR8X3zxhdDpdKKkpKTR/cOHDxczZsyw2/aXv/xFPPDAA3bbcnNzBQCRmZkpHdezZ09hs9mkmJdeekn07Nnzlm0kIudhTxQRuaXY2Fi7n8vKyvDCCy+gZ8+eMBgM8PX1xfHjx2/ZE9W3b1/pex8fH+h0OhQUFDQa+4tf/ALh4eHo2rUrnn76aaxcuRIVFRU3Pf/BgwexefNm+Pr6So/o6GgAwJkzZ6S4u+66CwqFQvo5Pj4ep06dgtVqven5ich5OLGciNySj4+P3c8vvPACUlJS8Pbbb6Nbt27w8vLCE088gZqampuex9PT0+5nhUIBm83WaKyfnx/27duHLVu24Pvvv8f8+fPx6quvYs+ePTAYDI0eU1ZWhocffhh/+9vfrtsXEhJy09yISF4sooioXdixYweeeeYZPProowDqi5eGid2OpFKpYDKZYDKZsGDBAhgMBmzatAmPPfYY1Gr1dT1HAwYMwBdffIGIiIibXkGYnp5u9/OuXbsQFRUFDw8Ph7eBiJqGw3lE1C5ERUXhyy+/xIEDB3Dw4EH85je/uWGPUkutX78eixcvxoEDB5CdnY1PP/0UNpsNPXr0AFB/9V96ejrOnTuHwsJC2Gw2TJs2DWazGWPHjsWePXtw5swZ/O9//8PEiRPtCq6cnBzMmjULmZmZWLVqFd5//33MmDHDofkTUfOwiCKiduHdd9+Fv78/hgwZgocffhgJCQkYMGCAQ5/DYDDgyy+/xP3334+ePXti6dKlWLVqFXr37g2gfkjRw8MDvXr1QseOHZGTk4PQ0FDs2LEDVqsVDzzwAGJiYjBz5kwYDAYolT/9Ez1+/HhUVlZi8ODBmDZtGmbMmOHUhUGJ6NYUQnChESKituzee+9F//79eUsaojaGPVFERERELcAiioiIiKgFOJxHRERE1ALsiSIiIiJqARZRRERERC3AIoqIiIioBVhEEREREbUAiygiIiKiFmARRURERNQCLKKIiIiIWoBFFBEREVEL/H9/hnxau87pkwAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# NoamDecayScheduler 是一个自定义或外部定义的学习率衰减调度器类。它需要接收配置 config 作为参数，可能实现了特定的学习率衰减方案\n",
    "class NoamDecayScheduler:\n",
    "    def __init__(self, config):\n",
    "        self.d_model = config[\"d_model\"]\n",
    "        self.warmup_steps = config[\"warmup_steps\"]\n",
    "\n",
    "    def __call__(self, step):\n",
    "        step += 1\n",
    "        arg1 = step ** (-0.5) #4000步之后是arg1\n",
    "        arg2 = step * (self.warmup_steps ** (-1.5))  #4000步之前是arg2\n",
    "\n",
    "        arg3 = self.d_model ** (-0.5)\n",
    "\n",
    "        return arg3 * np.minimum(arg1, arg2)\n",
    "\n",
    "\n",
    "temp_learning_rate_schedule = NoamDecayScheduler({\"d_model\": 512, \"warmup_steps\": 4000})\n",
    "#下面是学习率的设计图\n",
    "plt.plot(temp_learning_rate_schedule(np.arange(0, 40000)))\n",
    "plt.ylabel(\"Leraning rate\")\n",
    "plt.xlabel(\"Train step\")\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "XHj_EjzlN4yW"
   },
   "source": [
    "### 优化器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:27.240054200Z",
     "start_time": "2024-08-05T08:06:27.161089200Z"
    },
    "id": "1EVLKx2rN4yW"
   },
   "outputs": [],
   "source": [
    "from torch.optim.lr_scheduler import LambdaLR\n",
    "from torch.optim import Adam\n",
    "\n",
    "def get_optimizer(model, config):\n",
    "    base_lr = 0.1\n",
    "    beta1 = config[\"beta1\"] # Adam 的 beta1\n",
    "    beta2 = config[\"beta2\"] # Adam 的 beta2\n",
    "    eps = config[\"eps\"]\n",
    "    optimizer = Adam(model.parameters(), lr=base_lr, betas=(beta1, beta2), eps=eps)\n",
    "    lr_scheduler = NoamDecayScheduler(config) #config是一个字典，包含了学习率衰减的参数\n",
    "    # 使用 LambdaLR 调度器，它可以根据给定的函数 lr_lambda 调整学习率。这里将 lr_scheduler 作为函数传递给 LambdaLR，它包含了特定于模型或任务的学习率调度规则\n",
    "    scheduler = LambdaLR(optimizer, lr_lambda=lr_scheduler)\n",
    "    return optimizer, scheduler"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "JBhiO7O2N4yW"
   },
   "source": [
    "### Callback"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:36.478359Z",
     "start_time": "2024-08-05T08:06:27.161089200Z"
    },
    "id": "rWFMJwBkN4yX"
   },
   "outputs": [],
   "source": [
    "from torch.utils.tensorboard import SummaryWriter\n",
    "\n",
    "\n",
    "class TensorBoardCallback:\n",
    "    def __init__(self, log_dir, flush_secs=10):\n",
    "        \"\"\"\n",
    "        Args:\n",
    "            log_dir (str): dir to write log.\n",
    "            flush_secs (int, optional): write to dsk each flush_secs seconds. Defaults to 10.\n",
    "        \"\"\"\n",
    "        self.writer = SummaryWriter(log_dir=log_dir, flush_secs=flush_secs)\n",
    "\n",
    "    def draw_model(self, model, input_shape):\n",
    "        self.writer.add_graph(model, input_to_model=torch.randn(input_shape))\n",
    "\n",
    "    def add_loss_scalars(self, step, loss, val_loss):\n",
    "        self.writer.add_scalars(\n",
    "            main_tag=\"training/loss\",\n",
    "            tag_scalar_dict={\"loss\": loss, \"val_loss\": val_loss},\n",
    "            global_step=step,\n",
    "            )\n",
    "\n",
    "    def add_acc_scalars(self, step, acc, val_acc):\n",
    "        self.writer.add_scalars(\n",
    "            main_tag=\"training/accuracy\",\n",
    "            tag_scalar_dict={\"accuracy\": acc, \"val_accuracy\": val_acc},\n",
    "            global_step=step,\n",
    "        )\n",
    "\n",
    "    def add_lr_scalars(self, step, learning_rate):\n",
    "        self.writer.add_scalars(\n",
    "            main_tag=\"training/learning_rate\",\n",
    "            tag_scalar_dict={\"learning_rate\": learning_rate},\n",
    "            global_step=step,\n",
    "\n",
    "        )\n",
    "\n",
    "    def __call__(self, step, **kwargs):\n",
    "        # add loss\n",
    "        loss = kwargs.pop(\"loss\", None)\n",
    "        val_loss = kwargs.pop(\"val_loss\", None)\n",
    "        if loss is not None and val_loss is not None:\n",
    "            self.add_loss_scalars(step, loss, val_loss)\n",
    "        # add acc\n",
    "        acc = kwargs.pop(\"acc\", None)\n",
    "        val_acc = kwargs.pop(\"val_acc\", None)\n",
    "        if acc is not None and val_acc is not None:\n",
    "            self.add_acc_scalars(step, acc, val_acc)\n",
    "        # add lr\n",
    "        learning_rate = kwargs.pop(\"lr\", None)\n",
    "        if learning_rate is not None:\n",
    "            self.add_lr_scalars(step, learning_rate)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:36.486389200Z",
     "start_time": "2024-08-05T08:06:36.483880700Z"
    },
    "id": "64y_NBHMN4yX"
   },
   "outputs": [],
   "source": [
    "class SaveCheckpointsCallback:\n",
    "    def __init__(self, save_dir, save_step=5000, save_best_only=True):\n",
    "        \"\"\"\n",
    "        Save checkpoints each save_epoch epoch.\n",
    "        We save checkpoint by epoch in this implementation.\n",
    "        Usually, training scripts with pytorch evaluating model and save checkpoint by step.\n",
    "\n",
    "        Args:\n",
    "            save_dir (str): dir to save checkpoint\n",
    "            save_epoch (int, optional): the frequency to save checkpoint. Defaults to 1.\n",
    "            save_best_only (bool, optional): If True, only save the best model or save each model at every epoch.\n",
    "        \"\"\"\n",
    "        self.save_dir = save_dir\n",
    "        self.save_step = save_step\n",
    "        self.save_best_only = save_best_only\n",
    "        self.best_metrics = - np.inf\n",
    "\n",
    "        # mkdir\n",
    "        if not os.path.exists(self.save_dir):\n",
    "            os.mkdir(self.save_dir)\n",
    "\n",
    "    def __call__(self, step, state_dict, metric=None):\n",
    "        if step % self.save_step > 0:\n",
    "            return\n",
    "\n",
    "        if self.save_best_only:\n",
    "            assert metric is not None\n",
    "            if metric >= self.best_metrics:\n",
    "                # save checkpoints\n",
    "                torch.save(state_dict, os.path.join(self.save_dir, \"best.ckpt\"))\n",
    "                # update best metrics\n",
    "                self.best_metrics = metric\n",
    "        else:\n",
    "            torch.save(state_dict, os.path.join(self.save_dir, f\"{step}.ckpt\"))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:36.523266500Z",
     "start_time": "2024-08-05T08:06:36.494383100Z"
    },
    "id": "Uk4PEb70N4yX"
   },
   "outputs": [],
   "source": [
    "class EarlyStopCallback:\n",
    "    def __init__(self, patience=5, min_delta=0.01):\n",
    "        \"\"\"\n",
    "\n",
    "        Args:\n",
    "            patience (int, optional): Number of epochs with no improvement after which training will be stopped.. Defaults to 5.\n",
    "            min_delta (float, optional): Minimum change in the monitored quantity to qualify as an improvement, i.e. an absolute\n",
    "                change of less than min_delta, will count as no improvement. Defaults to 0.01.\n",
    "        \"\"\"\n",
    "        self.patience = patience\n",
    "        self.min_delta = min_delta\n",
    "        self.best_metric = - np.inf\n",
    "        self.counter = 0\n",
    "\n",
    "    def __call__(self, metric):\n",
    "        if metric >= self.best_metric + self.min_delta:\n",
    "            # update best metric\n",
    "            self.best_metric = metric\n",
    "            # reset counter\n",
    "            self.counter = 0\n",
    "        else:\n",
    "            self.counter += 1\n",
    "\n",
    "    @property\n",
    "    def early_stop(self):\n",
    "        return self.counter >= self.patience\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "_AB84Qx1N4yX"
   },
   "source": [
    "### training & valuating"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:36.525265400Z",
     "start_time": "2024-08-05T08:06:36.503642Z"
    },
    "id": "1mKPSFkON4yX"
   },
   "outputs": [],
   "source": [
    "@torch.no_grad()\n",
    "def evaluating(model, dataloader, loss_fct):\n",
    "    loss_list = []\n",
    "    for batch in dataloader:\n",
    "        encoder_inputs = batch[\"encoder_inputs\"]\n",
    "        encoder_inputs_mask = batch[\"encoder_inputs_mask\"]\n",
    "        decoder_inputs = batch[\"decoder_inputs\"]\n",
    "        decoder_labels = batch[\"decoder_labels\"]\n",
    "        decoder_labels_mask = batch[\"decoder_labels_mask\"]\n",
    "\n",
    "        # 前向计算\n",
    "        outputs = model(\n",
    "            encoder_inputs=encoder_inputs,\n",
    "            decoder_inputs=decoder_inputs,\n",
    "            encoder_inputs_mask=encoder_inputs_mask\n",
    "            )\n",
    "        logits = outputs.logits\n",
    "        loss = loss_fct(logits, decoder_labels, padding_mask=decoder_labels_mask)         # 验证集损失\n",
    "        loss_list.append(loss.cpu().item())\n",
    "\n",
    "    return np.mean(loss_list)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:36.549252Z",
     "start_time": "2024-08-05T08:06:36.514271Z"
    },
    "id": "PClBmtgWN4yY"
   },
   "outputs": [],
   "source": [
    "# 训练\n",
    "def training(\n",
    "    model,\n",
    "    train_loader,\n",
    "    val_loader,\n",
    "    epoch,\n",
    "    loss_fct,\n",
    "    optimizer,\n",
    "    scheduler=None,\n",
    "    tensorboard_callback=None,\n",
    "    save_ckpt_callback=None,\n",
    "    early_stop_callback=None,\n",
    "    eval_step=500,\n",
    "    ):\n",
    "    record_dict = {\n",
    "        \"train\": [],\n",
    "        \"val\": []\n",
    "    }\n",
    "\n",
    "    global_step = 1\n",
    "    model.train()\n",
    "    with tqdm(total=epoch * len(train_loader)) as pbar:\n",
    "        for epoch_id in range(epoch):\n",
    "            # training\n",
    "            for batch in train_loader:\n",
    "                encoder_inputs = batch[\"encoder_inputs\"]\n",
    "                encoder_inputs_mask = batch[\"encoder_inputs_mask\"]\n",
    "                decoder_inputs = batch[\"decoder_inputs\"]\n",
    "                decoder_labels = batch[\"decoder_labels\"]\n",
    "                decoder_labels_mask = batch[\"decoder_labels_mask\"]\n",
    "                # 梯度清空\n",
    "                optimizer.zero_grad()\n",
    "\n",
    "                # 前向计算\n",
    "                outputs = model(\n",
    "                    encoder_inputs=encoder_inputs,\n",
    "                    decoder_inputs=decoder_inputs,\n",
    "                    encoder_inputs_mask=encoder_inputs_mask\n",
    "                    )\n",
    "                logits = outputs.logits\n",
    "                loss = loss_fct(logits, decoder_labels, padding_mask=decoder_labels_mask)\n",
    "\n",
    "                # 梯度回传\n",
    "                loss.backward()\n",
    "\n",
    "                # 调整优化器，包括学习率的变动等\n",
    "                optimizer.step()\n",
    "                if scheduler is not None:\n",
    "                    scheduler.step() # 更新学习率\n",
    "\n",
    "                loss = loss.cpu().item()\n",
    "                # record\n",
    "                record_dict[\"train\"].append({\n",
    "                    \"loss\": loss, \"step\": global_step\n",
    "                })\n",
    "\n",
    "                # evaluating\n",
    "                if global_step % eval_step == 0:\n",
    "                    model.eval()\n",
    "                    val_loss = evaluating(model, val_loader, loss_fct)\n",
    "                    record_dict[\"val\"].append({\n",
    "                        \"loss\": val_loss, \"step\": global_step\n",
    "                    })\n",
    "                    model.train()\n",
    "\n",
    "                    # 1. 使用 tensorboard 可视化\n",
    "                    cur_lr = optimizer.param_groups[0][\"lr\"] if scheduler is None else scheduler.get_last_lr()[0]\n",
    "                    if tensorboard_callback is not None:\n",
    "                        tensorboard_callback(\n",
    "                            global_step,\n",
    "                            loss=loss, val_loss=val_loss,\n",
    "                            lr=cur_lr,\n",
    "                            )\n",
    "\n",
    "                    # 2. 保存模型权重 save model checkpoint\n",
    "                    if save_ckpt_callback is not None:\n",
    "                        save_ckpt_callback(global_step, model.state_dict(), metric=-val_loss)\n",
    "\n",
    "                    # 3. 早停 Early Stop\n",
    "                    if early_stop_callback is not None:\n",
    "                        early_stop_callback(-val_loss)\n",
    "                        if early_stop_callback.early_stop:\n",
    "                            print(f\"Early stop at epoch {epoch_id} / global_step {global_step}\")\n",
    "                            return record_dict\n",
    "\n",
    "                # udate step\n",
    "                global_step += 1\n",
    "                pbar.update(1)\n",
    "            pbar.set_postfix({\"epoch\": epoch_id, \"loss\": loss, \"val_loss\": val_loss})\n",
    "\n",
    "    return record_dict\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:06:36.628920Z",
     "start_time": "2024-08-05T08:06:36.541257800Z"
    },
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "khZqMS8pN4yY",
    "outputId": "2367a363-585b-4321-f7ea-cb11d9623008"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "load train dataset from wmt16\\.cache\\de2en_train_128.npy\n",
      "load val dataset from wmt16\\.cache\\de2en_val_128.npy\n"
     ]
    }
   ],
   "source": [
    "#模型的超参\n",
    "config = {\n",
    "    \"bos_idx\": 1,\n",
    "    \"eos_idx\": 3,\n",
    "    \"pad_idx\": 0,\n",
    "    \"src_vocab_size\": 23715,\n",
    "    \"trg_vocab_size\":12500,\n",
    "    \"max_length\": 128,\n",
    "    \"d_model\": 512,\n",
    "    \"dim_feedforward\": 2048, # FFN 的隐藏层大小\n",
    "    \"dropout\": 0.1,\n",
    "    \"layer_norm_eps\": 1e-6, # 层归一化的 epsilon, 防止除零错误\n",
    "    \"num_heads\": 8,\n",
    "    \"num_decoder_layers\": 6,\n",
    "    \"num_encoder_layers\": 6,\n",
    "    \"label_smoothing\": 0.1,\n",
    "    \"beta1\": 0.9, # Adam 的 beta1\n",
    "    \"beta2\": 0.98,\n",
    "    \"eps\": 1e-9,\n",
    "    \"warmup_steps\": 4_000,\n",
    "    \"share_embedding\": False, # 是否共享词向量\n",
    "    }\n",
    "\n",
    "\n",
    "\n",
    "# dataset\n",
    "train_ds = LangPairDataset(\"train\", max_length=config[\"max_length\"])\n",
    "val_ds = LangPairDataset(\"val\", max_length=config[\"max_length\"])\n",
    "# tokenizer\n",
    "# tokenizer = Tokenizer(word2idx=word2idx, idx2word=idx2word, max_length=config[\"max_length\"])\n",
    "batch_size = 2048\n",
    "# dataloader\n",
    "train_dl = DataLoader(train_ds, batch_size=batch_size, shuffle=True, collate_fn=collate_fct)\n",
    "test_dl = DataLoader(test_ds, batch_size=batch_size, shuffle=False, collate_fn=collate_fct)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T08:52:53.233851300Z",
     "start_time": "2024-08-05T08:52:51.458743700Z"
    },
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "模型参数量: 59038198\n"
     ]
    }
   ],
   "source": [
    "#计算模型参数量\n",
    "model = TransformerModel(config)\n",
    "print(f\"模型参数量: {sum(p.numel() for p in model.parameters() if p.requires_grad)}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-07T08:52:38.372364400Z",
     "start_time": "2024-05-07T08:52:38.191467100Z"
    },
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "63slV04gWLn8",
    "outputId": "5c5ede03-0f6f-48d5-a177-d961886ec340"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'bos_idx': 1,\n",
       " 'eos_idx': 3,\n",
       " 'pad_idx': 0,\n",
       " 'vocab_size': 9718,\n",
       " 'max_length': 128,\n",
       " 'd_model': 512,\n",
       " 'dim_feedforward': 2048,\n",
       " 'dropout': 0.1,\n",
       " 'layer_norm_eps': 1e-06,\n",
       " 'num_heads': 8,\n",
       " 'num_decoder_layers': 6,\n",
       " 'num_encoder_layers': 6,\n",
       " 'label_smoothing': 0.1,\n",
       " 'beta1': 0.9,\n",
       " 'beta2': 0.98,\n",
       " 'eps': 1e-09,\n",
       " 'warmup_steps': 4000,\n",
       " 'share_embedding': False}"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "config"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 49,
     "referenced_widgets": [
      "55146ac7395840dca847e0f63aa80561",
      "abb9bc76c0ce4634bd340be20c074b8c",
      "a89d790df59245fcaf26335d4903c9b4",
      "f837255914194dc792cf1514dee03dc5",
      "46a51a1719d8444eb5877720253d3c37",
      "013d2a6b90144432bbfb15136235faba",
      "2b82e42c34804b13bc83be4c7009d4e2",
      "9233439bdd6746c28ad4a20ef47799f6",
      "0e10428326bc436e8dbc079e89570bde",
      "0fe4ed7283c04496affe727c235d31c4",
      "0c0c7229347b49ffbb9a0f7bd41199b9"
     ]
    },
    "id": "tVO2zJ04N4yY",
    "outputId": "7d4079f5-65d4-4da1-9001-91aa5525250e"
   },
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "55146ac7395840dca847e0f63aa80561",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/280 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "epoch = 20\n",
    "\n",
    "# model\n",
    "model = TransformerModel(config)\n",
    "# 1. 定义损失函数 采用交叉熵损失\n",
    "loss_fct = CrossEntropyWithPadding(config)\n",
    "# 2. 定义优化器 采用 adam\n",
    "# Optimizers specified in the torch.optim package\n",
    "optimizer, scheduler = get_optimizer(model, config)\n",
    "\n",
    "# 1. tensorboard 可视化\n",
    "if not os.path.exists(\"runs\"):\n",
    "    os.mkdir(\"runs\")\n",
    "exp_name = \"translate-transformer-{}\".format(\"share\" if config[\"share_embedding\"] else \"not-share\")\n",
    "tensorboard_callback = TensorBoardCallback(f\"runs/{exp_name}\")\n",
    "# tensorboard_callback.draw_model(model, [1, MAX_LENGTH])\n",
    "# 2. save best\n",
    "if not os.path.exists(\"checkpoints\"):\n",
    "    os.makedirs(\"checkpoints\")\n",
    "save_ckpt_callback = SaveCheckpointsCallback(\n",
    "    f\"checkpoints/{exp_name}\", save_step=500, save_best_only=True)\n",
    "# 3. early stop\n",
    "early_stop_callback = EarlyStopCallback(patience=8)\n",
    "\n",
    "model = model.to(device)\n",
    "\n",
    "record = training(\n",
    "    model,\n",
    "    train_dl,\n",
    "    test_dl,\n",
    "    epoch,\n",
    "    loss_fct,\n",
    "    optimizer,\n",
    "    scheduler,\n",
    "    tensorboard_callback=tensorboard_callback,\n",
    "    save_ckpt_callback=save_ckpt_callback,\n",
    "    early_stop_callback=None,\n",
    "    eval_step=500\n",
    "    )\n",
    "\n",
    "# Training took 3.5 days on 8 P100 GPUs\n",
    "# We trained the base models for a total of 100,000 steps or 12 hours. For our big models,(described on the bottom line of table 3), step time was 1.0 seconds. The big models were trained for 300,000 steps (3.5 days)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "rTjbeFlIN4yZ"
   },
   "source": [
    "## 推理\n",
    "\n",
    "- 翻译项目的评估指标一般是BLEU4，感兴趣的同学自行了解并实现\n",
    "- 接下来进行翻译推理，并作出注意力的热度图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "WxsjkyQgN4yZ",
    "outputId": "5ce160c2-ce7e-4bc3-d2b6-a332c7fcf6a1"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Collecting fastBPE\n",
      "  Downloading fastBPE-0.1.0.tar.gz (35 kB)\n",
      "  Preparing metadata (setup.py) ... \u001B[?25l\u001B[?25hdone\n",
      "Building wheels for collected packages: fastBPE\n",
      "  Building wheel for fastBPE (setup.py) ... \u001B[?25l\u001B[?25hdone\n",
      "  Created wheel for fastBPE: filename=fastBPE-0.1.0-cp310-cp310-linux_x86_64.whl size=806588 sha256=b77d4a1091f1aa812ca7c62cb09e4397a6cb8ae13061a3c1aeb5bc104e3d8dc7\n",
      "  Stored in directory: /root/.cache/pip/wheels/13/5d/b9/4b8897941ebc9e8c6cc3f3ffd3ea5115731754269205098754\n",
      "Successfully built fastBPE\n",
      "Installing collected packages: fastBPE\n",
      "Successfully installed fastBPE-0.1.0\n"
     ]
    }
   ],
   "source": [
    "# !pip install Cython  # if failed to install fastBPE, try this line\n",
    "!pip install fastBPE #分词使用\n",
    "# 在 Windows 系统上并没有 sys/mman.h 文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 35
    },
    "id": "f6Ry1PcAn4k1",
    "outputId": "6393524e-e5c3-4f93-dd9d-f249ca52bc05"
   },
   "outputs": [
    {
     "data": {
      "application/vnd.google.colaboratory.intrinsic+json": {
       "type": "string"
      },
      "text/plain": [
       "'translate-transformer-not-share'"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "exp_name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T03:10:32.326542400Z",
     "start_time": "2024-08-05T03:10:31.006376300Z"
    },
    "id": "jT1Mqiq3N4yZ"
   },
   "outputs": [],
   "source": [
    "import torch\n",
    "\n",
    "state_dict = torch.load(f\"best.ckpt\", map_location=\"cpu\")\n",
    "\n",
    "# state_dict1 = torch.load(\"epoch125-step132426.ckpt\", map_location=\"cpu\")\n",
    "# state_dict = state_dict1[\"state_dict\"]\n",
    "\n",
    "# update keys by dropping `model`\n",
    "# for key in list(state_dict):\n",
    "#     state_dict[key.replace(\"model.\", \"\")] = state_dict.pop(key)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-08-05T03:10:46.720508800Z",
     "start_time": "2024-08-05T03:10:36.179313900Z"
    },
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "eKwIDdjgvTlO",
    "outputId": "35979ff2-a16d-4aa4-881a-8496e39e2469"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Defaulting to user installation because normal site-packages is not writeable\n",
      "Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple\n",
      "Collecting nltk\n",
      "  Using cached https://pypi.tuna.tsinghua.edu.cn/packages/a6/0a/0d20d2c0f16be91b9fa32a77b76c60f9baf6eba419e5ef5deca17af9c582/nltk-3.8.1-py3-none-any.whl (1.5 MB)\n",
      "Requirement already satisfied: click in c:\\users\\administrator\\appdata\\roaming\\python\\python312\\site-packages (from nltk) (8.1.7)\n",
      "Requirement already satisfied: joblib in c:\\users\\administrator\\appdata\\roaming\\python\\python312\\site-packages (from nltk) (1.4.2)\n",
      "Requirement already satisfied: regex>=2021.8.3 in c:\\users\\administrator\\appdata\\roaming\\python\\python312\\site-packages (from nltk) (2024.7.24)\n",
      "Requirement already satisfied: tqdm in c:\\users\\administrator\\appdata\\roaming\\python\\python312\\site-packages (from nltk) (4.66.4)\n",
      "Requirement already satisfied: colorama in c:\\users\\administrator\\appdata\\roaming\\python\\python312\\site-packages (from click->nltk) (0.4.6)\n",
      "Installing collected packages: nltk\n",
      "Successfully installed nltk-3.8.1\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n",
      "[notice] A new release of pip is available: 24.1.2 -> 24.2\n",
      "[notice] To update, run: python.exe -m pip install --upgrade pip\n"
     ]
    }
   ],
   "source": [
    "!pip install nltk"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "id": "WVksjIhL_pt9"
   },
   "outputs": [],
   "source": [
    "!rm -r wmt16/.cache"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "2MY69-6WWSjp",
    "outputId": "911d9066-7917-4917-b5cc-d679a1c63865"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['a man in an orange hat starring at something .']"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tokenizer.decode([[   5,   16,    6,   23,  150,   80, 8248,   35,  232,    4,    3]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 101,
     "referenced_widgets": [
      "c9db4cd83b7b4f53a0fa93b8c365debd",
      "a972aba7913b48c6973ae27bff5b9d1d",
      "22aa774ab39e4fd78b0ff08d430d2b5d",
      "9a01f02fb99b4b81ac487d23bc5daf4a",
      "19f846338f6b48c9930b58575641e5b8",
      "7d293204dc1b4d97bb5ee670787c7b7d",
      "ea8fa440f320435aa75c9bef75bc3f08",
      "4e64bcb87e584beda0408a0aa5a659ae",
      "b077d7562d814df5b6d839464dd4122f",
      "5a28babf4e2e4393bdc1a093034885ab",
      "be07d518c21149d196c610fd57b1eaec"
     ]
    },
    "id": "5QgodlOJfgKj",
    "outputId": "2907bad2-7cb1-4295-c8b0-77ac0dabf398"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "load test dataset from wmt16/.cache/de2en_test_128.npy\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "c9db4cd83b7b4f53a0fa93b8c365debd",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "0it [00:00, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "testing loss: 3.258438676626829\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.5708733100076216"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from nltk.translate.bleu_score import sentence_bleu\n",
    "# load checkpoints\n",
    "model = TransformerModel(config)\n",
    "model.load_state_dict(state_dict)\n",
    "\n",
    "loss_fct = CrossEntropyWithPadding(config)\n",
    "# from dataset import LangPairDataset\n",
    "test_ds = LangPairDataset(\"test\", max_length=128, data_dir=\"./wmt16\")\n",
    "test_dl = DataLoader(test_ds, batch_size=1, collate_fn=partial(collate_fct, tokenizer=tokenizer))\n",
    "\n",
    "model = model.to(device)\n",
    "model.eval()\n",
    "collect = {}\n",
    "loss_collect = []\n",
    "\n",
    "predictions = []\n",
    "answers = []\n",
    "# 初始化BLEU分数列表\n",
    "bleu_scores = []\n",
    "for idx, batch in tqdm(enumerate(test_dl)):\n",
    "    encoder_inputs = batch[\"encoder_inputs\"]\n",
    "    encoder_inputs_mask = batch[\"encoder_inputs_mask\"]\n",
    "    decoder_inputs = batch[\"decoder_inputs\"]\n",
    "    decoder_labels = batch[\"decoder_labels\"]\n",
    "    # print(decoder_labels.cpu())\n",
    "    # decoder_labels1=tokenizer.decode(decoder_labels.cpu().numpy())\n",
    "    # print(decoder_labels1)\n",
    "    # 前向计算\n",
    "    outputs = model(\n",
    "        encoder_inputs=encoder_inputs,\n",
    "        decoder_inputs=decoder_inputs,\n",
    "        encoder_inputs_mask=encoder_inputs_mask\n",
    "        )\n",
    "    loss = loss_fct(outputs.logits, decoder_labels)         # 验证集损失\n",
    "\n",
    "    # print(outputs.logits.shape, decoder_labels.shape)\n",
    "\n",
    "    # loss = loss_fct(outputs.logits[:, :decoder_labels.shape[1]], decoder_labels)         # 验证集损失\n",
    "    # outputs = model.infer(encoder_inputs=encoder_inputs)\n",
    "    # print(outputs.logits.shape)\n",
    "    preds = outputs.logits.argmax(dim=-1) # 预测结果，[1,seq_len]\n",
    "    # print(preds.shape)\n",
    "    #把preds转为英文单词\n",
    "    preds = tokenizer.decode(preds.cpu().numpy()) #['预测句子']\n",
    "    # predictions.append(preds)\n",
    "    # print(preds)\n",
    "    #把decoder_labels转为英文单词\n",
    "    decoder_labels = tokenizer.decode(decoder_labels.cpu().numpy()) #['标签句子']\n",
    "    # answers.append(decoder_labels)\n",
    "    # print(decoder_labels)\n",
    "    belu=sentence_bleu([decoder_labels[0].split()],preds[0].split(),weights=(1, 0, 0, 0))\n",
    "    bleu_scores.append(belu)\n",
    "    collect[idx] = {\"loss\": loss.item(), \"src_inputs\": encoder_inputs, \"trg_inputs\": decoder_inputs, \"mask\": encoder_inputs_mask, \"trg_labels\": decoder_labels, \"preds\": preds}\n",
    "    loss_collect.append(loss.item())\n",
    "    # break\n",
    "\n",
    "# sort collect by value\n",
    "collect = sorted(collect.items(), key=lambda x: x[1][\"loss\"])\n",
    "print(f\"testing loss: {np.array(loss_collect).mean()}\")\n",
    "sum(bleu_scores) / len(bleu_scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-06T13:16:14.099749Z",
     "start_time": "2024-05-06T13:16:13.991811900Z"
    },
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 535,
     "referenced_widgets": [
      "40f7e3754ad44b33acfe0a80b3648a3a",
      "b1e51beac50f4947a9dd235d8aa87603",
      "8cd9e9702e114ebc856f56975544ede8",
      "b7c7a718a8654956947108969557ca83",
      "20a27d1ec76f4d85b1ffe99401fbb5b7",
      "e0ddf3970b3e4248bc87d4649fa9c448",
      "d7bdde54e2534c49a207540bd258d3ae",
      "22484000400842f0b6e245dc610acbba",
      "a66a5b4ff37d4dafa4ba3081aa1359f4",
      "0b7866c29e5f4afe9b92de15f1b88c3e",
      "333e84a304184c57af1821620ae80f6a"
     ]
    },
    "id": "KGSym4CbN4ya",
    "outputId": "f5e9c4c2-c92e-44e6-c83a-5cb720305428"
   },
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "40f7e3754ad44b33acfe0a80b3648a3a",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/128 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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f/NLrh0+/PBDPfvss3ryySfPuaxNmzb1extyc3N15MiRiz6EESVXSVifSqOCggIdP378os57vBQUPGfo2bOnqlSp4j2eet++fWrYsKGqVKmiOnXq6Ouvv9bUqVPVq1cvm1sa2DZt2qQbbrhBLVq00IIFC3TbbbcV2S1fp04du5sIlChXXHHFRR9L/v333/u5NbgYdvYntWrVOu9jLpdLO3bs8HmmXYKCzr7CxqkTo518knlhYaEGDx6s+fPn64orrtCECROKdRglzq20rk9W+c9//qOsrCz17t3be98LL7ygMWPGqKCgQNdff70++OADxcTE+DSXQ9rOsGrVKk2bNs17+5133lFsbKzWr1+vkJAQvfzyy/rHP/5BwXOZ7Not/8ADDygtLU0RERFF7j969Kj69++vt956y2/ZpUVmZqYSExPP+nJujNHu3btVvXp1m1oW2Lp27Wp3E3hvi8nO/mTnzp0+n2dJZdey7t27V0OGDNH8+fO1b9++s0ae8tUX40OHDumJJ57Q3LlzNW3aNHXo0EGSNGDAAH366afq27ev5syZo/79+2vmzJk+ySzNStNnxw4TJkzQX//6V+/tFStWaNSoUXruuefUqFEjPf300xozZowmTJjg01z28JyhbNmy+t///uc9BKFTp05q0qSJXnzxRUlSRkaG2rZtq6ysLDubGfDO98Xp1GP++uIUHBysPXv2nHXYwf79+xUfH6+CggK/5JYm53uNs7KyVKlSJX4dC2C8t8VDf+JsHTt2VGZmph5//HElJCSc1Z916dLFJzl33323srKydM011yg9PV3vvfeePvnkE915551atmyZWrdurR9++EHXX3+9fv/9d59knguff/hCpUqVNHfuXO+Q7oMHD1Z6err3wrmzZ8/WgAEDtHXrVp/msofnDJGRkTp06JC3g1qzZo369Onjfdzlcvn12juFhYWaNm2a9xejMy8Wt2DBAr9lW6lWrVrn3XDWqlXL5xvOnJwcGWNkjNHhw4dVpkwZ72OFhYWaPXs2x177yPkuHnvkyJEirzsCD+9t8djZn5SWvuSUd999V//85z+1c+dOrVy5UjVq1NCkSZNUq1YtnxUeZ1q2bJmWLl2q5s2b+2X+p8yZM0crVqxQrVq1dOWVVyomJkY5OTkaOXKkWrduLUkKDw/XsWPH/NqO8/0+npeXp7CwML9mW82O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/KzPw4EDB/ySW7t2bb355pvq0KFDkVG13nnnHY0bN07p6ek+z7z22mvVo0cP9e/fXxEREdq4caNq1aql/v37a+vWrZozZ47PM0+x4/O/YcOGIrfz8/O1bt06TZgwQS+88MIfXtPvUti1PknSu+++6z0nbOXKlapRo4YmTpyo2rVrq0uXLn7LtdqJEyfOeUHmO++8U4MGDfLLBbQpeC7SiRMndOLECb9f6dbj8cjj8XhHXfnggw+0fPly1atXT4888ojfrspthZiYmCJf9I8ePWr5BuXxxx/XtGnTdMstt5yz8Jg4caJfcsuVK6f//ve/atiwoV/mX5J06tRJxhi99957io2NlSRlZWXpnnvuUVBQkL766iubWxj4nn/+eY0aNUoNGjRQ5cqVzxq0wF+FO++tb1jRnzi5LznTqRP4z+e+++7zS25qaqr+/e9/66233tKNN96o2bNn66efftKgQYM0cuRI9e/f3+eZy5YtU8eOHXXPPfd4By9JT0/XihUrtHjxYrVs2dLnmaeUpM//V199pZdeekmLFi3y+bztWp/eeOMNjRo1SgMHDtTzzz+vH3/8UbVr19a0adM0ffp0LVy40C+5pQUFzzm8/fbb+v7773XllVfq7rvv1vDhwzV+/HgVFBTo+uuv18yZMxUXF+e3/OPHj2vjxo1n7YFwuVx+vaigv/3RRuR0/tqgVKhQQe+8847lI5786U9/0sSJE/0yak9JU65cOa1atUrJyclF7t+wYYOuuuoqHTlyxKaWOUdMTIwmTpyo3r17W5rLe1t8dvYnTu1LSgpjjMaOHavU1FTvsOxut1tDhgzRmDFj/Ja7Y8cOpaamasOGDTpy5IhatGihp5566qzPpa+VpM//tm3b1KxZMx09etSyTH9LSkrS2LFjvRcgPbXHcNOmTUpJSdH+/fvtbqJPrFmzRi1btjzvYZB5eXn6/PPPdfvtt/s22OdnBQW4559/3pQtW9Z06NDBxMbGmkceecTEx8ebcePGmRdffNFUq1bNPPLII37L//rrr02FChWMy+U6awoKCvJbrtV69eplpk6davmJ1wkJCWbLli2WZhpjzPz5803btm3NwoULzf79+012dnaRyUliYmLM8uXLz7p/2bJlJiYmxoYWOU/lypVNRkaG5bm8t8VjZ3/i9L7k9O3mmdtTq7eveXl55scffzSrV682hw8f9mtWr169zFtvvWXLoCV2fP7PfC8PHTpkNm/ebO644w7TrFkzn+acL9Oq9alMmTLegUZOH5AiIyPDlClTxm+5VgsKCioy6lxERIR3WY0x5rfffvPLNopBC84wbdo0TZ06VT179tTatWvVpk0bzZo1y3ul7CZNmuiRRx7xW37//v11++23a9SoURccp9zXtm7dqoULF57zvJZRo0b5PM/tdmvcuHHq27evqlSpovbt2yslJUXt27f36QXMzvTEE08oLS1Nr732mqXXaujQoYMk6frrry+Saxw4aEHnzp310EMPaerUqd6LLq5evVqPPPKIbrvtNr9mW70e22XAgAF69dVX//C6Ur5m53sbiOzsT+zqSyRrPocxMTHas2ePKlWqpOjo6HNuz63avoaFhSkpKcmvGadnpaam6sEHH7S075Ts+fyf6701xigxMVEzZ870WU5JWJ9q1aql9evXq0aNGkXunzNnjho1auSXTDuYMw4sO/P2+e67XBzSdga3261t27Z5LxTndru1ceNG7wl6v/zyi2rVqnXWVat9JTIyUuvWrbP05N/Jkyfr0UcfVYUKFRQfH3/W+QD+vCL3L7/8oiVLlmjx4sVavHixMjIylJCQoJ9//tlnGWee1LhgwQLFxsaqcePGZx3H/sknn/gs93SLFy++4ON2XrHb1w4dOqT77rtP//nPf7yvb35+vrp06aJp06YpKirKL7l2rsdW69atmxYsWKC4uDhL12O73ttAZWd/YkdfIln3OVy8eLF3MBgrt6/FOUneX59DyZq+80x2fP7PfG+DgoJUsWJF1a1b13t+mq9y7FifTjdlyhQ9++yzGj9+vPr06aMpU6Zo+/btSk1N1ZQpU3TnnXf6JddqQUFB+u2337yjDZ5++J508sL0VapU8XlhyR6eM+Tn5xcZHSIsLKzIl4mQkBC//lr017/+VYsWLbK0k3r++ef1wgsv6KmnnrIs85SYmBjFxcUpJiZG0dHRCgkJUcWKFX2aceZGuFu3bj6d/8Vo3769Dh06pKlTp3qH80xKSlKfPn38/iUxPT1dmZmZZ32p8ucvcp9//rm2bdvmHaUoKSlJdevW9UveKXaux3a8xv4Ynehicu14bwOVnf2JHX2JZN3n8PQvne3bt9fSpUv1r3/9S9u3b9dHH32kqlWr6t1331WtWrV8mnux22t/H0FgRd95Jjs+/6fe59O3sQcPHvSO7OWrbaxd69PpHnzwQZUtW1YjRoxQbm6u7rrrLlWtWlVpaWmOKXbsRMFzDunp6frtt98kndyt9r///c97Mp6/Txp77bXX1KNHDy1duvScw83+7W9/83nmwYMH1aNHD5/P90KGDx+uRYsWad26dWrUqJHat2+voUOH6tprr1VMTIxPs95++23v/48dOyaPx6Ny5cpJknbt2qXPPvtMjRo10s033+zT3NOtXbtWf/7zn1WmTBnvoQATJ07U2LFjNW/ePLVo0cLnmTt27FC3bt30ww8/yOVyeXcRn+qI/Vm4T506VRMnTtTWrVslSfXq1dPAgQP14IMP+i3TjvXYrtf49ddft2U9lux5bwOZXf2JHX2JZM/n8OOPP1avXr109913a926dcrLy5MkZWdna+zYsZo9e7bPsk7vT2bMmKGePXue83lPPvmkzzJPZ2XfeS5Wf/537Nih7t27a+PGjZZtY61cn0537NgxdevWTXfffbdyc3O1adMmLV++XNWqVfNLnp1s2S76/KygAHfqhM7znejp7xM+p0yZYkJCQkz58uVNjRo1TM2aNb1TrVq1/JL5wAMPmDfeeMMv8z4fl8tlKlWqZFJTUy0dRODGG2/0LuvBgwdN5cqVTbVq1UyZMmXM66+/7rfcq6++2vTu3dvk5+d778vPzzf33Xefueaaa/yS2blzZ9OlSxfz+++/m/Lly5v09HSzdOlS07p1a7NkyRK/ZBpjzMiRI025cuXM0KFDzeeff24+//xzM3ToUFO+fHm/XD35FDvWY7teY7vWY7ve20BlZ39iR19ijD2fw+bNm5vp06cbY4qe7P3999+bypUr+y03KirKzJ49+6z7Bw0aZOLj4/2SaVffaYw9n/8zt7E//vij37exdq1Pdm3XrWbXdpGC5wy7du26qMlfKleubF544QVTWFjot4wzjR071lSoUMHcd9995uWXXzZpaWlFJn9Yv369SUtLM926dTMVKlQwVapUMT179jT/+te//LoRj4uLM5s2bTLGGDN58mTTtGlTU1hYaGbNmmUaNmzot9wyZcqYzZs3n3X/jz/+aMqWLeuXzLi4OLNhwwZjjDGRkZHmf//7nzHm5IhxzZs390umMcZUqFDBvP/++2fd//7775u4uDi/5dqxHtv1Gtu1Htv13gYqO/sTO/oSY+z5HJYtW9bs3LnTGFP0C+r27duN2+32S6Yxxnz55ZcmKirKLF261Hvf448/bhISEs65vfcFu/pOY+z5/NuxjbVrfbJru241u7aLFDyn2bBhQ7E6h02bNhX5xd4XYmJiLB9u8vRf/s6c/PlL4OnWr19v7rvvPhMSEuLXPWhly5Y1P/30kzHGmB49ephnn33WGGNMZmam3woPY4ypVKmSmTt37ln3z5kzx1SqVMkvmdHR0WbHjh3GGGNq165tFixYYIwxZtu2bX5d1qioqHMOmbxlyxYTFRXlt1w71mO7XmO71mO73ttAZHd/YkdfYow9n8NatWqZb775xhhT9Avq9OnTTaNGjfySecp7771nYmJizNq1a82jjz5qqlSpYumeF6v6TmPs+fzbsY21a32ya7tuJTu3ixQ8pwkKCjL79u276OefOXa4LwwcONC88MILPp1nSeTxeMx///tfM378eHPrrbeamJgYExwcbK644gozcOBAv+UmJyebtLQ0k5mZaSIjI82KFSuMMcasXbvWr7uq+/fvb6pVq2ZmzpxpMjMzTWZmppkxY4apVq2aGTBggF8yr776avPpp58aY4zp2bOn+fOf/2yWLVtm7r33XtO4cWO/ZBpz8hfOQYMGnXX/E088YR577DG/5drBrtfYrvW4NL23l8vu/qS09CXGnNyrlJSUZFatWmUiIiLM0qVLzb///W9TsWJF88orr/g9/x//+Idxu92mWrVqZuvWrX7NsqvvNMaez78d21i71ie7tutWsnO7yKAFpzHGaOTIkQoPD7+o5/tjKNHCwkK9+OKLmjt3rpo2bXrWiaYTJkzwSc7gwYM1ZswYlStXToMHDz7v81wul8aPH++TzNPFxsbqyJEjatasmdq3b6++ffvqmmuuUXR0tM+zTjdq1CjdddddGjRokG644Qa1bdtWkjRv3jxdccUVfst9+eWX5XK5dO+996qgoECSFBoaqkcffVTjxo3zS+aIESO8V6F+7rnn1LlzZ11zzTWKi4vTBx984NOs09chl8ulKVOmaN68ebryyislnbxWQ2Zmpu69916f59q5Hlv5Gp/OyvXYrvf2YnTo0EE7duzQjh07LM/+I3b3J1b1JZL9n8OhQ4fK4/HohhtuUG5urq699lq53W4NGTJE/fv392nW+ZavYsWKatGihV5//XXvfb58jU+xuu+0+/NvxzbWyvXpdHZ9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",
      "text/plain": [
       "<Figure size 1000x500 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "['man in white shirt on a boat in a small boat.']"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import re\n",
    "from fastBPE import fastBPE\n",
    "from sacremoses import MosesDetokenizer, MosesTokenizer\n",
    "\n",
    "# `MosesTokenizer` 和 `MosesDetokenizer` 是来自 `sacremoses` 库的工具，用于自然语言处理中的分词（Tokenization）和去标记化（Detokenization）。这些工具主要用于对文本进行预处理和后处理，通常在处理自然语言处理任务时会用到。\n",
    "#\n",
    "# ### MosesTokenizer：\n",
    "# - **作用**：将原始文本分割成单词和标点符号。\n",
    "# - **特点**：基于 Moses 翻译工具中使用的分词方法。\n",
    "# - **功能**：\n",
    "#   - 将句子分割成单词和标点符号。\n",
    "#   - 处理缩写、连字符、标点等特殊情况。\n",
    "#   - 对文本进行标记化，方便后续处理。\n",
    "#\n",
    "# ### MosesDetokenizer：\n",
    "# - **作用**：将分词后的文本重新组合成原始的句子。\n",
    "# - **特点**：用于对分词后的文本进行还原，使其恢复为可读的句子形式。\n",
    "# - **功能**：\n",
    "#   - 将分词后的单词和标点符号重新组合成句子。\n",
    "#   - 处理分词后的标点、缩写等情况，使得结果更加自然和可读。\n",
    "#\n",
    "# 这些工具通常在文本预处理和后处理过程中使用，对输入的文本进行标记化和去标记化，是一种常用的处理方式。在自然语言处理任务中，对文本进行正确的分词和还原是很重要的，而 `MosesTokenizer` 和 `MosesDetokenizer` 提供了方便、高效的工具来处理这些任务。\n",
    "\n",
    "class Translator:\n",
    "    def __init__(self, model, src_tokenizer, trg_tokenizer):\n",
    "        self.bpe = fastBPE(\"./wmt16/bpe.10000\", \"./wmt16/vocab\")\n",
    "        self.mose_tokenizer = MosesTokenizer(lang=\"de\")\n",
    "        self.mose_detokenizer = MosesDetokenizer(lang=\"en\")\n",
    "        self.model = model\n",
    "        self.model.eval()\n",
    "        self.src_tokenizer = src_tokenizer\n",
    "        self.trg_tokenizer = trg_tokenizer\n",
    "        self.pattern = re.compile(r'(@@ )|(@@ ?$)')\n",
    "\n",
    "    def draw_attention_map(self, attn_scores, cross_attn_scores, src_words_list, trg_words_list):\n",
    "        \"\"\"绘制注意力热力图\n",
    "        attn_scores (numpy.ndarray): 表示自注意力机制（self-attention）分数。\n",
    "        cross_attn_scores (numpy.ndarray): 表示交叉注意力机制的注意力分数。\n",
    "        src_words_list (list): 源语言句子的单词列表。\n",
    "        trg_words_list (list): 目标语言句子的单词列表。\n",
    "        \"\"\"\n",
    "        assert len(attn_scores.shape) == 3, \"attn_scores shape should be \" \\\n",
    "            f\"[num heads, target sequence length, target sequence length], but got {attn_scores.shape}\"\n",
    "        attn_scores = attn_scores[:, :len(trg_words_list), :len(trg_words_list)]\n",
    "\n",
    "        assert len(cross_attn_scores.shape) == 3, \"attn_scores shape should be \" \\\n",
    "            f\"[num heads, target sequence length, source sequence length], but got {cross_attn_scores.shape}\"\n",
    "        cross_attn_scores = cross_attn_scores[:, :len(trg_words_list), :len(src_words_list)]\n",
    "\n",
    "        num_heads, trg_len, src_len = cross_attn_scores.shape\n",
    "\n",
    "        fig = plt.figure(figsize=(10, 5), constrained_layout=True) # constrained_layout=True 自动调整子图参数，使之填充整个图像区域\n",
    "        grid = plt.GridSpec(trg_len, trg_len + src_len, wspace=0.1, hspace=0.1)# wspace,hspace 控制子图之间的间距\n",
    "        #下面是attn_scores的热力图\n",
    "        self_map = fig.add_subplot(grid[:,:trg_len]) #  添加子图\n",
    "        self_map.matshow(attn_scores.mean(dim=0), cmap='viridis') # 绘制热力图，cmap表示颜色,dim=0表示对第0维求均值\n",
    "        self_map.set_yticks(range(trg_len), trg_words_list, fontsize=10)\n",
    "        self_map.set_xticks(range(trg_len), [\"[BOS]\"] + trg_words_list[:-1], rotation=90)\n",
    "        #下面是cross_attn_scores的热力图\n",
    "        cross_map = fig.add_subplot(grid[:, trg_len:])\n",
    "        cross_map.matshow(cross_attn_scores.mean(dim=0), cmap='viridis')\n",
    "        cross_map.set_yticks(range(trg_len), [], fontsize=6)\n",
    "        cross_map.set_xticks(range(src_len), src_words_list, rotation=90)\n",
    "\n",
    "        plt.show()\n",
    "\n",
    "    def draw_attention_maps(self, attn_scores, cross_attn_scores, src_words_list, trg_words_list, heads_list):\n",
    "        \"\"\"绘制注意力热力图\n",
    "\n",
    "        Args:\n",
    "            - scores (numpy.ndarray): shape = [source sequence length, target sequence length]\n",
    "        \"\"\"\n",
    "        assert len(attn_scores.shape) == 3, \"attn_scores shape should be \" \\\n",
    "            f\"[num heads, target sequence length, target sequence length], but got {attn_scores.shape}\"\n",
    "        attn_scores = attn_scores[:, :len(trg_words_list), :len(trg_words_list)]\n",
    "\n",
    "        assert len(cross_attn_scores.shape) == 3, \"attn_scores shape should be \" \\\n",
    "            f\"[num heads, target sequence length, source sequence length], but got {cross_attn_scores.shape}\"\n",
    "        cross_attn_scores = cross_attn_scores[:, :len(trg_words_list), :len(src_words_list)]\n",
    "        # cross_attn_scores = cross_attn_scores[:, :len(src_words_list), :len(src_words_list)]\n",
    "\n",
    "        num_heads, trg_len, src_len = cross_attn_scores.shape\n",
    "        fig, axes = plt.subplots(2, len(heads_list), figsize=(5 * len(heads_list), 10))\n",
    "        for i, heads_idx in enumerate(heads_list):\n",
    "            axes[0, i].matshow(attn_scores[heads_idx], cmap='viridis')\n",
    "            axes[0, i].set_yticks(range(trg_len), trg_words_list)\n",
    "            axes[0, i].set_xticks(range(trg_len), [\"[BOS]\"] + trg_words_list[:-1], rotation=90)\n",
    "            axes[0, i].set_title(f\"head {heads_idx}\")\n",
    "            axes[1, i].matshow(cross_attn_scores[heads_idx], cmap='viridis')\n",
    "            axes[1, i].set_yticks(range(trg_len), trg_words_list)\n",
    "            axes[1, i].set_xticks(range(src_len), src_words_list, rotation=90)\n",
    "            axes[1, i].set_title(f\"head {heads_idx}\")\n",
    "\n",
    "        plt.show()\n",
    "\n",
    "\n",
    "    def __call__(self, sentence_list, heads_list=None, layer_idx=-1):\n",
    "        # 将输入句子列表转换为小写，并使用 MosesTokenizer 进行分词处理。\n",
    "        sentence_list = [\" \".join(self.mose_tokenizer.tokenize(s.lower())) for s in sentence_list]\n",
    "        # 将分词后的结果进行 BPE 编码，得到 tokens_list。\n",
    "        tokens_list = [s.split() for s in self.bpe.apply(sentence_list)]\n",
    "        # 使用 src_tokenizer 对 tokens_list 进行编码，同时添加起始标记 ([BOS]) 和结束标记 ([EOS])。\n",
    "        encoder_input, attn_mask = self.src_tokenizer.encode(\n",
    "            tokens_list,\n",
    "            add_bos=True,\n",
    "            add_eos=True,\n",
    "            return_mask=True,\n",
    "            )\n",
    "        encoder_input = torch.Tensor(encoder_input).to(dtype=torch.int64)\n",
    "        # 使用模型的 infer 方法对编码器输入进行推理，得到输出结果 outputs\n",
    "        outputs = model.infer(encoder_inputs=encoder_input, encoder_inputs_mask=attn_mask)\n",
    "\n",
    "        preds = outputs.preds.numpy()\n",
    "        # 使用目标语言的 trg_tokenizer 对预测序列进行解码，得到解码后的目标语言句子列表 trg_decoded。\n",
    "        trg_decoded = self.trg_tokenizer.decode(preds, split=True, remove_eos=False, remove_bos=False, remove_pad=False)\n",
    "        # 使用源语言的 src_tokenizer 对编码器输入进行解码，得到解码后的源语言句子列表 src_decoded。为下面绘制热力图做准备。\n",
    "        src_decoded = self.src_tokenizer.decode(\n",
    "            encoder_input.numpy(),\n",
    "            split=True,\n",
    "            remove_bos=False,\n",
    "            remove_eos=False\n",
    "            )\n",
    "\n",
    "        # post processed attn scores\n",
    "        # outputs.decoder_attentions[-1]  # the last layer of self-attention scores\n",
    "\n",
    "        # draw the attention map of the last decoder block\n",
    "        for attn_score, cross_attn_score, src, trg in zip(\n",
    "            outputs.decoder_self_attn_scores[layer_idx], outputs.decoder_cross_attn_scores[layer_idx], src_decoded, trg_decoded):\n",
    "            if heads_list is None:# 如果没有指定heads_list，就画单个热力图\n",
    "                self.draw_attention_map(\n",
    "                    attn_score,\n",
    "                    cross_attn_score,\n",
    "                    src,\n",
    "                    trg,\n",
    "                )\n",
    "            else:# 如果指定了heads_list，就画多个热力图\n",
    "                self.draw_attention_maps(\n",
    "                    attn_score,\n",
    "                    cross_attn_score,\n",
    "                    src,\n",
    "                    trg,\n",
    "                    heads_list=heads_list,\n",
    "                    )\n",
    "        return [self.mose_detokenizer.tokenize(self.pattern.sub(\"\", s).split()) for s in self.trg_tokenizer.decode(preds)] #将解码后的目标语言句子列表返回，并使用 mose_detokenizer 进行去标记化，最终得到翻译后的结果。\n",
    "\n",
    "\n",
    "# sentence_list = [\n",
    "#     \"Mann in einem kleinen weißen Boot auf einem See.\",  # Man in a small white boat on a lake.\n",
    "#     \"Ein Mann mit einem Eimer und ein Mädchen mit einem Hut am Strand.\", # A man with a bucket and a girl in a hat on the beach.\n",
    "#     \"Drei Männer auf Pferden während eines Rennens.\",  # Three men on horses during a race.\n",
    "#     \"Ein Mann und eine Frau essen zu Abend\",  # 一个男人和一个女人在吃晚餐\n",
    "# ]\n",
    "sentence_list = [\n",
    "    \"Mann in einem kleinen weißen Boot auf einem See.\",  # Man in a small white boat on a lake.\n",
    "    # \"Ein Mann mit einem Eimer und ein Mädchen mit einem Hut am Strand.\", # A man with a bucket and a girl in a hat on the beach.\n",
    "    # \"Drei Männer auf Pferden während eines Rennens.\",  # Three men on horses during a race.\n",
    "    # \"Ein Mann und eine Frau essen zu Abend\",  # 一个男人和一个女人在吃晚餐\n",
    "]\n",
    "\n",
    "# load checkpoints\n",
    "model = TransformerModel(config)\n",
    "model.load_state_dict(state_dict)\n",
    "translator = Translator(model.cpu(), tokenizer, tokenizer)\n",
    "translator(\n",
    "    sentence_list,\n",
    "    layer_idx=-1,\n",
    "    # heads_list=[0, 1, 2, 3, 4, 5, 6, 7]\n",
    "    )\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "e0WkUQuUe-Cy",
    "outputId": "433e3d70-4f34-4376-e4a3-1b8834e71f88"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "translate-transformer-not-share\n"
     ]
    }
   ],
   "source": [
    "!ls checkpoints"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "_1ZLtdahywWf"
   },
   "outputs": [],
   "source": [
    "# prompt: 把best.ckpt复制到云盘内\n",
    "\n",
    "!cp -r checkpoints/translate-transformer-not-share/best.ckpt /content/drive/MyDrive/transformer-de-en\n"
   ]
  }
 ],
 "metadata": {
  "accelerator": "GPU",
  "colab": {
   "gpuType": "T4",
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.8"
  },
  "orig_nbformat": 4,
  "widgets": {
   "application/vnd.jupyter.widget-state+json": {
    "00fe6a550df547cea5b1e0d84c1a3f5f": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "FloatProgressModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "FloatProgressModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "ProgressView",
      "bar_style": "success",
      "description": "",
      "description_tooltip": null,
      "layout": "IPY_MODEL_83f345f7424c43929d7a304cbfb6d0fe",
      "max": 9714,
      "min": 0,
      "orientation": "horizontal",
      "style": "IPY_MODEL_58d69d086f644e89937347e1f9261d6f",
      "value": 9714
     }
    },
    "013d2a6b90144432bbfb15136235faba": {
     "model_module": "@jupyter-widgets/base",
     "model_module_version": "1.2.0",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "0b7866c29e5f4afe9b92de15f1b88c3e": {
     "model_module": "@jupyter-widgets/base",
     "model_module_version": "1.2.0",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "0c0c7229347b49ffbb9a0f7bd41199b9": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "DescriptionStyleModel",
     "state": {
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "DescriptionStyleModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "StyleView",
      "description_width": ""
     }
    },
    "0e10428326bc436e8dbc079e89570bde": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "ProgressStyleModel",
     "state": {
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "ProgressStyleModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "StyleView",
      "bar_color": null,
      "description_width": ""
     }
    },
    "0fe4ed7283c04496affe727c235d31c4": {
     "model_module": "@jupyter-widgets/base",
     "model_module_version": "1.2.0",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "19f846338f6b48c9930b58575641e5b8": {
     "model_module": "@jupyter-widgets/base",
     "model_module_version": "1.2.0",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "20a27d1ec76f4d85b1ffe99401fbb5b7": {
     "model_module": "@jupyter-widgets/base",
     "model_module_version": "1.2.0",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "22484000400842f0b6e245dc610acbba": {
     "model_module": "@jupyter-widgets/base",
     "model_module_version": "1.2.0",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "22aa774ab39e4fd78b0ff08d430d2b5d": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "FloatProgressModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "FloatProgressModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "ProgressView",
      "bar_style": "success",
      "description": "",
      "description_tooltip": null,
      "layout": "IPY_MODEL_4e64bcb87e584beda0408a0aa5a659ae",
      "max": 1,
      "min": 0,
      "orientation": "horizontal",
      "style": "IPY_MODEL_b077d7562d814df5b6d839464dd4122f",
      "value": 1
     }
    },
    "2b82e42c34804b13bc83be4c7009d4e2": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "DescriptionStyleModel",
     "state": {
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "DescriptionStyleModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "StyleView",
      "description_width": ""
     }
    },
    "333e84a304184c57af1821620ae80f6a": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "DescriptionStyleModel",
     "state": {
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "DescriptionStyleModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "StyleView",
      "description_width": ""
     }
    },
    "40f7e3754ad44b33acfe0a80b3648a3a": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "HBoxModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "HBoxModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "HBoxView",
      "box_style": "",
      "children": [
       "IPY_MODEL_b1e51beac50f4947a9dd235d8aa87603",
       "IPY_MODEL_8cd9e9702e114ebc856f56975544ede8",
       "IPY_MODEL_b7c7a718a8654956947108969557ca83"
      ],
      "layout": "IPY_MODEL_20a27d1ec76f4d85b1ffe99401fbb5b7"
     }
    },
    "434ac4c51db74681942d2d3bd869b1df": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "DescriptionStyleModel",
     "state": {
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "DescriptionStyleModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "StyleView",
      "description_width": ""
     }
    },
    "46a51a1719d8444eb5877720253d3c37": {
     "model_module": "@jupyter-widgets/base",
     "model_module_version": "1.2.0",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "4e64bcb87e584beda0408a0aa5a659ae": {
     "model_module": "@jupyter-widgets/base",
     "model_module_version": "1.2.0",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": "20px"
     }
    },
    "55146ac7395840dca847e0f63aa80561": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "HBoxModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "HBoxModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "HBoxView",
      "box_style": "",
      "children": [
       "IPY_MODEL_abb9bc76c0ce4634bd340be20c074b8c",
       "IPY_MODEL_a89d790df59245fcaf26335d4903c9b4",
       "IPY_MODEL_f837255914194dc792cf1514dee03dc5"
      ],
      "layout": "IPY_MODEL_46a51a1719d8444eb5877720253d3c37"
     }
    },
    "58d69d086f644e89937347e1f9261d6f": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "ProgressStyleModel",
     "state": {
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "ProgressStyleModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "StyleView",
      "bar_color": null,
      "description_width": ""
     }
    },
    "5a28babf4e2e4393bdc1a093034885ab": {
     "model_module": "@jupyter-widgets/base",
     "model_module_version": "1.2.0",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "673bd3773a374261a01cfc48081c27f3": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "DescriptionStyleModel",
     "state": {
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "DescriptionStyleModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "StyleView",
      "description_width": ""
     }
    },
    "7190c928edb040c3a523cdd2e3f45572": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "HBoxModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "HBoxModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "HBoxView",
      "box_style": "",
      "children": [
       "IPY_MODEL_990741ff083d457587665d8f620b69c3",
       "IPY_MODEL_00fe6a550df547cea5b1e0d84c1a3f5f",
       "IPY_MODEL_fab8b1e3187841ee894b92859fa4821b"
      ],
      "layout": "IPY_MODEL_f9b0d916e1a64c2a9f384e42f3d5dcab"
     }
    },
    "7d293204dc1b4d97bb5ee670787c7b7d": {
     "model_module": "@jupyter-widgets/base",
     "model_module_version": "1.2.0",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "83f345f7424c43929d7a304cbfb6d0fe": {
     "model_module": "@jupyter-widgets/base",
     "model_module_version": "1.2.0",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "8cd9e9702e114ebc856f56975544ede8": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "FloatProgressModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "FloatProgressModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "ProgressView",
      "bar_style": "danger",
      "description": "",
      "description_tooltip": null,
      "layout": "IPY_MODEL_22484000400842f0b6e245dc610acbba",
      "max": 128,
      "min": 0,
      "orientation": "horizontal",
      "style": "IPY_MODEL_a66a5b4ff37d4dafa4ba3081aa1359f4",
      "value": 12
     }
    },
    "8cf462fa996c41b18fb4571e0a757363": {
     "model_module": "@jupyter-widgets/base",
     "model_module_version": "1.2.0",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "9233439bdd6746c28ad4a20ef47799f6": {
     "model_module": "@jupyter-widgets/base",
     "model_module_version": "1.2.0",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "990741ff083d457587665d8f620b69c3": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "HTMLModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "HTMLModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "HTMLView",
      "description": "",
      "description_tooltip": null,
      "layout": "IPY_MODEL_a78199650ecc47bd81f482a2671b563a",
      "placeholder": "​",
      "style": "IPY_MODEL_673bd3773a374261a01cfc48081c27f3",
      "value": "100%"
     }
    },
    "9a01f02fb99b4b81ac487d23bc5daf4a": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "HTMLModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "HTMLModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "HTMLView",
      "description": "",
      "description_tooltip": null,
      "layout": "IPY_MODEL_5a28babf4e2e4393bdc1a093034885ab",
      "placeholder": "​",
      "style": "IPY_MODEL_be07d518c21149d196c610fd57b1eaec",
      "value": " 957/? [00:18&lt;00:00, 51.31it/s]"
     }
    },
    "a66a5b4ff37d4dafa4ba3081aa1359f4": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "ProgressStyleModel",
     "state": {
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "ProgressStyleModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "StyleView",
      "bar_color": null,
      "description_width": ""
     }
    },
    "a78199650ecc47bd81f482a2671b563a": {
     "model_module": "@jupyter-widgets/base",
     "model_module_version": "1.2.0",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "a89d790df59245fcaf26335d4903c9b4": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "FloatProgressModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "FloatProgressModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "ProgressView",
      "bar_style": "success",
      "description": "",
      "description_tooltip": null,
      "layout": "IPY_MODEL_9233439bdd6746c28ad4a20ef47799f6",
      "max": 280,
      "min": 0,
      "orientation": "horizontal",
      "style": "IPY_MODEL_0e10428326bc436e8dbc079e89570bde",
      "value": 280
     }
    },
    "a972aba7913b48c6973ae27bff5b9d1d": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "HTMLModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "HTMLModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "HTMLView",
      "description": "",
      "description_tooltip": null,
      "layout": "IPY_MODEL_7d293204dc1b4d97bb5ee670787c7b7d",
      "placeholder": "​",
      "style": "IPY_MODEL_ea8fa440f320435aa75c9bef75bc3f08",
      "value": ""
     }
    },
    "abb9bc76c0ce4634bd340be20c074b8c": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "HTMLModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "HTMLModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "HTMLView",
      "description": "",
      "description_tooltip": null,
      "layout": "IPY_MODEL_013d2a6b90144432bbfb15136235faba",
      "placeholder": "​",
      "style": "IPY_MODEL_2b82e42c34804b13bc83be4c7009d4e2",
      "value": ""
     }
    },
    "b077d7562d814df5b6d839464dd4122f": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "ProgressStyleModel",
     "state": {
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "ProgressStyleModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "StyleView",
      "bar_color": null,
      "description_width": ""
     }
    },
    "b1e51beac50f4947a9dd235d8aa87603": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "HTMLModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "HTMLModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "HTMLView",
      "description": "",
      "description_tooltip": null,
      "layout": "IPY_MODEL_e0ddf3970b3e4248bc87d4649fa9c448",
      "placeholder": "​",
      "style": "IPY_MODEL_d7bdde54e2534c49a207540bd258d3ae",
      "value": "  9%"
     }
    },
    "b7c7a718a8654956947108969557ca83": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "HTMLModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "HTMLModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "HTMLView",
      "description": "",
      "description_tooltip": null,
      "layout": "IPY_MODEL_0b7866c29e5f4afe9b92de15f1b88c3e",
      "placeholder": "​",
      "style": "IPY_MODEL_333e84a304184c57af1821620ae80f6a",
      "value": " 12/128 [00:00&lt;00:01, 73.96it/s]"
     }
    },
    "be07d518c21149d196c610fd57b1eaec": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "DescriptionStyleModel",
     "state": {
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "DescriptionStyleModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "StyleView",
      "description_width": ""
     }
    },
    "c9db4cd83b7b4f53a0fa93b8c365debd": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "HBoxModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "HBoxModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "HBoxView",
      "box_style": "",
      "children": [
       "IPY_MODEL_a972aba7913b48c6973ae27bff5b9d1d",
       "IPY_MODEL_22aa774ab39e4fd78b0ff08d430d2b5d",
       "IPY_MODEL_9a01f02fb99b4b81ac487d23bc5daf4a"
      ],
      "layout": "IPY_MODEL_19f846338f6b48c9930b58575641e5b8"
     }
    },
    "d7bdde54e2534c49a207540bd258d3ae": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "DescriptionStyleModel",
     "state": {
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "DescriptionStyleModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "StyleView",
      "description_width": ""
     }
    },
    "e0ddf3970b3e4248bc87d4649fa9c448": {
     "model_module": "@jupyter-widgets/base",
     "model_module_version": "1.2.0",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "ea8fa440f320435aa75c9bef75bc3f08": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "DescriptionStyleModel",
     "state": {
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "DescriptionStyleModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "StyleView",
      "description_width": ""
     }
    },
    "f837255914194dc792cf1514dee03dc5": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "HTMLModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "HTMLModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "HTMLView",
      "description": "",
      "description_tooltip": null,
      "layout": "IPY_MODEL_0fe4ed7283c04496affe727c235d31c4",
      "placeholder": "​",
      "style": "IPY_MODEL_0c0c7229347b49ffbb9a0f7bd41199b9",
      "value": " 21020/? [21:30&lt;00:00, 15.32it/s, epoch=19, loss=2.61, val_loss=3.41]"
     }
    },
    "f9b0d916e1a64c2a9f384e42f3d5dcab": {
     "model_module": "@jupyter-widgets/base",
     "model_module_version": "1.2.0",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "fab8b1e3187841ee894b92859fa4821b": {
     "model_module": "@jupyter-widgets/controls",
     "model_module_version": "1.5.0",
     "model_name": "HTMLModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "HTMLModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "HTMLView",
      "description": "",
      "description_tooltip": null,
      "layout": "IPY_MODEL_8cf462fa996c41b18fb4571e0a757363",
      "placeholder": "​",
      "style": "IPY_MODEL_434ac4c51db74681942d2d3bd869b1df",
      "value": " 9714/9714 [00:00&lt;00:00, 236744.37it/s]"
     }
    }
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
